Index: COperation.java
===================================================================
--- COperation.java	(revision 263)
+++ COperation.java	(revision 264)
@@ -51,20 +51,20 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * Clase que implementa las operaciones de tranformacion de 
- * coordenadas entre dos CRSs.
- * 
+ * Clase que implementa las operaciones de tranformacion de coordenadas entre
+ * dos CRSs.
+ *
  * @author Miguel García Jiménez (garciajimenez.miguel@gmail.com)
  * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
  *
  */
 
-//public class COperation implements ICOperation {
+// public class COperation implements ICOperation {
 public class COperation implements ICoordTrans {
-	
-	private static final Logger logger = LoggerFactory.getLogger(COperation.class); 
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(COperation.class);
 	/**
 	 * CRS Fuente
 	 */
@@ -74,183 +74,242 @@
 	 */
 	private ICrs targetCrs;
 	/**
-	 * CRS con los parámetros de transformación (puede representar el
-	 * CRS fuente o destino, dependiendo de <code>paramsInTarget</code>).
+	 * CRS con los parámetros de transformación (puede representar el CRS fuente
+	 * o destino, dependiendo de <code>paramsInTarget</code>).
 	 */
 	private CrsProj paramsCrsProj = null;
 	/**
-	 * Indica si los parámetros de transformación van asociados al CRS
-	 * fuente (<code>false</code>) o al destino (<code>true</code>)
+	 * Indica si los parámetros de transformación van asociados al CRS fuente (
+	 * <code>false</code>) o al destino (<code>true</code>)
 	 */
 	private boolean paramsInTarget;
-	
+
 	/**
 	 * parámetros de transformación para el CRS fuente en el formato proj4
 	 */
 	private String sourceParams = null;
-	
+
 	/**
 	 * parámetros de transformación para el CRS destino en el formato proj4
 	 */
 	private String targetParams = null;
-	
+
 	private CrsProj source = null;
-	
+
 	private CrsProj target = null;
-	
-	
+
 	/**
 	 * Constructor.
-	 * 
-	 * @param from CRS fuente.
-	 * @param to CRS destino.
+	 *
+	 * @param from
+	 *            CRS fuente.
+	 * @param to
+	 *            CRS destino.
 	 * @throws CrsException
 	 */
 	public COperation(ICrs from, ICrs to) throws CrsException {
-		sourceCrs =  from;
-		targetCrs =  to;
+		sourceCrs = from;
+		targetCrs = to;
 		source = sourceCrs.getCrsProj();
 		target = targetCrs.getCrsProj();
 	}
-	
+
 	/**
 	 * Construcctor.
-	 * 
-	 * @param sourceCrs CRS fuente.
-	 * @param targetCrs CRS destino.
-	 * @param sourceParams Parámetros de transformación para la fuente (en formato proj4).
-	 * @param targetParams Parámetros de transformación para el destino (en formato proj4).
+	 *
+	 * @param sourceCrs
+	 *            CRS fuente.
+	 * @param targetCrs
+	 *            CRS destino.
+	 * @param sourceParams
+	 *            Parámetros de transformación para la fuente (en formato
+	 *            proj4).
+	 * @param targetParams
+	 *            Parámetros de transformación para el destino (en formato
+	 *            proj4).
 	 * @throws CrsException
 	 */
-	public COperation(ICrs sourceCrs, ICrs targetCrs, String sourceParams, String targetParams) throws CrsException {
+	public COperation(ICrs sourceCrs, ICrs targetCrs, String sourceParams,
+			String targetParams) throws CrsException {
 		this.sourceCrs = sourceCrs;
 		this.targetCrs = targetCrs;
 		this.sourceParams = sourceParams;
 		this.targetParams = targetParams;
-		
-		if(sourceParams != null)
-			source = new CrsProj(sourceCrs.getProj4String()+sourceParams);
+
+		if (sourceParams != null)
+			source = new CrsProj(sourceCrs.getProj4String() + sourceParams);
 		else
 			source = sourceCrs.getCrsProj();
-		if(targetParams != null)
-			target = new CrsProj(targetCrs.getProj4String()+targetParams);
+		if (targetParams != null)
+			target = new CrsProj(targetCrs.getProj4String() + targetParams);
 		else
 			target = targetCrs.getCrsProj();
 	}
 
 	/**
-	 * Realiza la operación de transformación sobre un punto.
-	 * Si exiten parámetros de transformación (<code>paramsCrsProj</code>) se utilizan
-	 * en lugar del CRS fuente o destino, según indique <code>paramsInTarget</code>.
-	 * @throws OperationCrsException 
-	 * 
+	 * Realiza la operación de transformación sobre un punto. Si exiten
+	 * parámetros de transformación (<code>paramsCrsProj</code>) se utilizan en
+	 * lugar del CRS fuente o destino, según indique <code>paramsInTarget</code>
+	 * .
+	 *
+	 * @throws OperationCrsException
+	 *
 	 */
-	private Point2D operate(Point2D pt) throws CrsException, OperationCrsException {
-		double x[] = {pt.getX()};
-		double y[] = {pt.getY()};
-		double z[] = {0D};
+	private Point2D operate(Point2D pt) throws CrsException,
+			OperationCrsException {
+		double x[] = { pt.getX() };
+		double y[] = { pt.getY() };
+		double z[] = { 0D };
 		int errno = 0;
-		
-			errno = JNIBaseCrs.operate( x , y, z,source,target);
-			if (errno != -38) // "failed to load NAD27-83 correction file" (pj_strerrno.c)
-				return new Point2D.Double(x[0],y[0]);
-			else{
-				x[0] = pt.getX();
-				y[0] = pt.getY();
-				z[0] = 0D;
-				JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), targetCrs.getCrsProj());
-				return new Point2D.Double(x[0],y[0]);
+
+		try {
+			errno = JNIBaseCrs.operate(x, y, z, source, target);
+		} catch (OperationCrsException e) {
+			// Parche para arreglar posible error al transformar de latlong a proyectadas cuando la y es +/- 90
+			if (e.getErrno() == -20) {
+				source.reloadCrs();
+				target.reloadCrs();
+				if (!sourceCrs.isProjected() && targetCrs.isProjected()) {
+					if (Math.abs((pt.getY() - 90.0)) < 0.000000001) {
+						x[0] = pt.getX();
+						y[0] = 89.99999999;
+						z[0] = 0D;
+						errno = JNIBaseCrs.operate(x, y, z, source, target);
+					} else if (Math.abs(pt.getY() + 90.0) < 0.000000001) {
+						x[0] = pt.getX();
+						y[0] = -89.99999999;
+						z[0] = 0D;
+						errno = JNIBaseCrs.operate(x, y, z, source, target);
+					}
+				}
 			}
-			
-			/*
-			if (paramsCrsProj != null){
-				if (paramsInTarget)
-					errno = JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
-				else
-					errno = JNIBaseCrs.operate( x , y, z,paramsCrsProj,targetCrs.getCrsProj());
-				if (errno != -38) // "failed to load NAD27-83 correction file" (pj_strerrno.c)
-					return new Point2D.Double(x[0],y[0]);
-			}
-			
-			// Si el punto estaba fuera del ámbito del nadgrid operamos sin nadgrid (convertimos)
+		}
+		if (errno != -38) // "failed to load NAD27-83 correction file"
+							// (pj_strerrno.c)
+			return new Point2D.Double(x[0], y[0]);
+		else {
 			x[0] = pt.getX();
 			y[0] = pt.getY();
 			z[0] = 0D;
-			JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), targetCrs.getCrsProj());
-			return new Point2D.Double(x[0],y[0]);*/
-	//	System.out.println("x="+x[0]+"y="+y[0]);
-	//	if(!targetCrs.isProjected())
-	//		return new Point2D.Double(x[0]*((180)/Math.PI),y[0]*((180)/Math.PI));
-	//	else
+			try {
+				errno = JNIBaseCrs.operate(x, y, z, sourceCrs.getCrsProj(),
+						targetCrs.getCrsProj());
+			} catch (OperationCrsException e) {
+				if (e.getErrno() == -20) {
+					if (!sourceCrs.isProjected() && targetCrs.isProjected()) {
+						if (Math.abs((pt.getY() - 90.0)) < 0.000000001) {
+							x[0] = pt.getX();
+							y[0] = 89.99999999;
+							z[0] = 0D;
+							errno = JNIBaseCrs.operate(x, y, z,
+									sourceCrs.getCrsProj(),
+									targetCrs.getCrsProj());
+						} else if (Math.abs(pt.getY() + 90.0) < 0.000000001) {
+							x[0] = pt.getX();
+							y[0] = -89.99999999;
+							z[0] = 0D;
+							errno = JNIBaseCrs.operate(x, y, z,
+									sourceCrs.getCrsProj(),
+									targetCrs.getCrsProj());
+						}
+					}
+				}
+			}
+			return new Point2D.Double(x[0], y[0]);
+		}
+
+		/*
+		 * if (paramsCrsProj != null){ if (paramsInTarget) errno =
+		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
+		 * else errno = JNIBaseCrs.operate( x , y,
+		 * z,paramsCrsProj,targetCrs.getCrsProj()); if (errno != -38) //
+		 * "failed to load NAD27-83 correction file" (pj_strerrno.c) return new
+		 * Point2D.Double(x[0],y[0]); }
+		 *
+		 * // Si el punto estaba fuera del ámbito del nadgrid operamos sin
+		 * nadgrid (convertimos) x[0] = pt.getX(); y[0] = pt.getY(); z[0] = 0D;
+		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(),
+		 * targetCrs.getCrsProj()); return new Point2D.Double(x[0],y[0]);
+		 */
+		// System.out.println("x="+x[0]+"y="+y[0]);
+		// if(!targetCrs.isProjected())
+		// return new Point2D.Double(x[0]*((180)/Math.PI),y[0]*((180)/Math.PI));
+		// else
 	}
 
 	/**
-	 * Realiza la operación de transformación sobre un punto.
-	 * Si exiten parámetros de transformación (<code>paramsCrsProj</code>) se utilizan
-	 * en lugar del CRS fuente o destino, según indique <code>paramsInTarget</code>.
-	 * @throws CrsException 
-	 * 
+	 * Realiza la operación de transformación sobre un punto. Si exiten
+	 * parámetros de transformación (<code>paramsCrsProj</code>) se utilizan en
+	 * lugar del CRS fuente o destino, según indique <code>paramsInTarget</code>
+	 * .
+	 *
+	 * @throws CrsException
+	 *
 	 */
-	//TODO Eliminar este método. Me vale con el operate(Point2D).
-	private double [] operate(double []ptOrig) throws OperationCrsException, CrsException {
-		double x[] = {ptOrig[0]};
-		double y[] = {ptOrig[1]};
-		double z[] = {ptOrig[2]};
+	// TODO Eliminar este método. Me vale con el operate(Point2D).
+	private double[] operate(double[] ptOrig) throws OperationCrsException,
+			CrsException {
+		double x[] = { ptOrig[0] };
+		double y[] = { ptOrig[1] };
+		double z[] = { ptOrig[2] };
 		int errno = 0;
 
-			CrsProj source;
-			CrsProj target;
-			if(sourceParams != null)
-				source = new CrsProj(sourceCrs.getProj4String()+sourceParams);
-			else
-				source = sourceCrs.getCrsProj();
-			if(targetParams != null)
-				target = new CrsProj(targetCrs.getProj4String()+targetParams);
-			else
-				target = targetCrs.getCrsProj();
-			
-			errno = JNIBaseCrs.operate( x , y, z,source,target);
-			if (errno != -38){ // "failed to load NAD27-83 correction file" (pj_strerrno.c)
-				double ptDest[] = {x[0], y[0], z[0]};
-				return ptDest;
-			}
-			
-			/*if (paramsCrsProj != null){
-				if (paramsInTarget)
-					errno = JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
-				else
-					errno = JNIBaseCrs.operate( x , y, z,paramsCrsProj,targetCrs.getCrsProj());
-				if (errno != -38){ // "failed to load NAD27-83 correction file" (pj_strerrno.c)
-					double ptDest[] = {x[0], y[0], z[0]};
-					return ptDest;
-				}
-			}*/
-			
-			// Si el punto estaba fuera del ámbito del nadgrid operamos sin nadgrid (convertimos)
-			 x[0] = ptOrig[0];
-			 y[0] = ptOrig[1];
-			 z[0] = ptOrig[2];
-			 JNIBaseCrs.operate(x, y, z,sourceCrs.getCrsProj(), targetCrs.getCrsProj());
-			 double ptDest[] = {x[0], y[0], z[0]};
-			 return ptDest;
+		CrsProj source;
+		CrsProj target;
+		if (sourceParams != null)
+			source = new CrsProj(sourceCrs.getProj4String() + sourceParams);
+		else
+			source = sourceCrs.getCrsProj();
+		if (targetParams != null)
+			target = new CrsProj(targetCrs.getProj4String() + targetParams);
+		else
+			target = targetCrs.getCrsProj();
+
+		errno = JNIBaseCrs.operate(x, y, z, source, target);
+		if (errno != -38) { // "failed to load NAD27-83 correction file"
+							// (pj_strerrno.c)
+			double ptDest[] = { x[0], y[0], z[0] };
+			return ptDest;
+		}
+
+		/*
+		 * if (paramsCrsProj != null){ if (paramsInTarget) errno =
+		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
+		 * else errno = JNIBaseCrs.operate( x , y,
+		 * z,paramsCrsProj,targetCrs.getCrsProj()); if (errno != -38){ //
+		 * "failed to load NAD27-83 correction file" (pj_strerrno.c) double
+		 * ptDest[] = {x[0], y[0], z[0]}; return ptDest; } }
+		 */
+
+		// Si el punto estaba fuera del ámbito del nadgrid operamos sin nadgrid
+		// (convertimos)
+		x[0] = ptOrig[0];
+		y[0] = ptOrig[1];
+		z[0] = ptOrig[2];
+		JNIBaseCrs.operate(x, y, z, sourceCrs.getCrsProj(),
+				targetCrs.getCrsProj());
+		double ptDest[] = { x[0], y[0], z[0] };
+		return ptDest;
 	}
 
 	public IProjection getPOrig() {
-		return (IProjection)sourceCrs;
+		return (IProjection) sourceCrs;
 	}
 
 	public IProjection getPDest() {
-		return (IProjection)targetCrs;
+		return (IProjection) targetCrs;
 	}
 
-	public Point2D convert(Point2D ptOrig, Point2D ptDest){
+	public Point2D convert(Point2D ptOrig, Point2D ptDest) {
 		try {
 			ptDest = operate(ptOrig);
 		} catch (CrsException e) {
-			logger.error("Can't operate over point orig ("+ptOrig.toString()+").",e);
+			logger.error("Can't operate over point orig (" + ptOrig.toString()
+					+ ").", e);
 			throw new IllegalStateException(e.getMessage());
-		}catch (OperationCrsException e) {
-			logger.error("Can't operate over point orig ("+ptOrig.toString()+").",e);
+		} catch (OperationCrsException e) {
+			logger.error("Can't operate over point orig (" + ptOrig.toString()
+					+ ").", e);
 			throw new IllegalStateException(e.getMessage());
 		}
 		return ptDest;
@@ -259,53 +318,49 @@
 	public Rectangle2D convert(Rectangle2D rect) {
 		Point2D pt1 = new Point2D.Double(rect.getMinX(), rect.getMinY());
 		Point2D pt2 = new Point2D.Double(rect.getMaxX(), rect.getMaxY());
-        Point2D pt3 = new Point2D.Double(rect.getMinX(), rect.getMaxY());
-        Point2D pt4 = new Point2D.Double(rect.getMaxX(), rect.getMinY());
+		Point2D pt3 = new Point2D.Double(rect.getMinX(), rect.getMaxY());
+		Point2D pt4 = new Point2D.Double(rect.getMaxX(), rect.getMinY());
 		try {
 			pt1 = operate(pt1);
-            pt2 = operate(pt2);
-            pt3 = operate(pt3);
-            pt4 = operate(pt4);
+			pt2 = operate(pt2);
+			pt3 = operate(pt3);
+			pt4 = operate(pt4);
 		} catch (CrsException e) {
-			logger.error("Can't operate over rect ("+rect.toString()+").",e);
+			logger.error("Can't operate over rect (" + rect.toString() + ").",
+					e);
 			throw new IllegalStateException(e.getMessage());
-		}catch (OperationCrsException e) {
-			logger.error("Can't operate over rect ("+rect.toString()+").",e);
+		} catch (OperationCrsException e) {
+			logger.error("Can't operate over rect (" + rect.toString() + ").",
+					e);
 			throw new IllegalStateException(e.getMessage());
 		}
-		
-		double min_x = Math.min(
-		    Math.min(pt1.getX(), pt2.getX()),
-		    Math.min(pt3.getX(), pt4.getX()));
-        double min_y = Math.min(
-            Math.min(pt1.getY(), pt2.getY()),
-            Math.min(pt3.getY(), pt4.getY()));
-        double max_x = Math.max(
-            Math.max(pt1.getX(), pt2.getX()),
-            Math.max(pt3.getX(), pt4.getX()));
-        double max_y = Math.max(
-            Math.max(pt1.getY(), pt2.getY()),
-            Math.max(pt3.getY(), pt4.getY()));
-        
-        return new Rectangle2D.Double(
-            min_x, min_y, max_x - min_x, max_y - min_y);
+
+		double min_x = Math.min(Math.min(pt1.getX(), pt2.getX()),
+				Math.min(pt3.getX(), pt4.getX()));
+		double min_y = Math.min(Math.min(pt1.getY(), pt2.getY()),
+				Math.min(pt3.getY(), pt4.getY()));
+		double max_x = Math.max(Math.max(pt1.getX(), pt2.getX()),
+				Math.max(pt3.getX(), pt4.getX()));
+		double max_y = Math.max(Math.max(pt1.getY(), pt2.getY()),
+				Math.max(pt3.getY(), pt4.getY()));
+
+		return new Rectangle2D.Double(min_x, min_y, max_x - min_x, max_y
+				- min_y);
 	}
 
-	
 	public ICoordTrans getInverted() {
 		COperation operation;
 		try {
-			operation = new COperation(targetCrs, sourceCrs,targetParams,sourceParams);
+			operation = new COperation(targetCrs, sourceCrs, targetParams,
+					sourceParams);
 			return operation;
 		} catch (CrsException e) {
-			logger.error("Can't get operation.",e);
+			logger.error("Can't get operation.", e);
 			return null;
 		}
 	}
-/*	
-	public void setParamsCrsProj(CrsProj paramsCrs, boolean inTarget){
-		this.paramsInTarget = inTarget;
-		this.paramsCrsProj = paramsCrs;
-	}
-	*/
+	/*
+	 * public void setParamsCrsProj(CrsProj paramsCrs, boolean inTarget){
+	 * this.paramsInTarget = inTarget; this.paramsCrsProj = paramsCrs; }
+	 */
 }
