Revision 359 org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/COperation.java

View differences:

COperation.java
45 45

  
46 46
import org.cresques.cts.ICoordTrans;
47 47
import org.cresques.cts.IProjection;
48
import org.gvsig.crs.proj.CrsProj;
49
import org.gvsig.crs.proj.JNIBaseCrs;
50
import org.gvsig.crs.proj.OperationCrsException;
48
import org.gdal.gdal.gdal;
49
import org.gdal.osr.CoordinateTransformation;
51 50
import org.slf4j.Logger;
52 51
import org.slf4j.LoggerFactory;
53 52

  
53
import org.gvsig.crs.proj.CrsProj;
54
import org.gvsig.crs.proj.OperationCrsException;
55

  
54 56
/**
55 57
 * Clase que implementa las operaciones de tranformacion de coordenadas entre
56 58
 * dos CRSs.
......
63 65
// public class COperation implements ICOperation {
64 66
public class COperation implements ICoordTrans {
65 67

  
66
	private static final Logger logger = LoggerFactory
67
			.getLogger(COperation.class);
68
	/**
69
	 * CRS Fuente
70
	 */
71
	private ICrs sourceCrs;
72
	/**
73
	 * CRS Destino
74
	 */
75
	private ICrs targetCrs;
76
	/**
77
	 * CRS con los par?metros de transformaci?n (puede representar el CRS fuente
78
	 * o destino, dependiendo de <code>paramsInTarget</code>).
79
	 */
80
	private CrsProj paramsCrsProj = null;
81
	/**
82
	 * Indica si los par?metros de transformaci?n van asociados al CRS fuente (
83
	 * <code>false</code>) o al destino (<code>true</code>)
84
	 */
85
	private boolean paramsInTarget;
68
    private static final Logger logger = LoggerFactory.getLogger(COperation.class);
69
    /**
70
     * CRS Fuente
71
     */
72
    private ICrs sourceCrs;
73
    /**
74
     * CRS Destino
75
     */
76
    private ICrs targetCrs;
77
    /**
78
     * CRS con los par?metros de transformaci?n (puede representar el CRS fuente
79
     * o destino, dependiendo de <code>paramsInTarget</code>).
80
     */
81
    private CrsProj paramsCrsProj = null;
82
    /**
83
     * Indica si los par?metros de transformaci?n van asociados al CRS fuente (
84
     * <code>false</code>) o al destino (<code>true</code>)
85
     */
86
    private boolean paramsInTarget;
86 87

  
87
	/**
88
	 * par?metros de transformaci?n para el CRS fuente en el formato proj4
89
	 */
90
	private String sourceParams = null;
88
    /**
89
     * par?metros de transformaci?n para el CRS fuente en el formato proj4
90
     */
91
    private String sourceParams = null;
91 92

  
92
	/**
93
	 * par?metros de transformaci?n para el CRS destino en el formato proj4
94
	 */
95
	private String targetParams = null;
93
    /**
94
     * par?metros de transformaci?n para el CRS destino en el formato proj4
95
     */
96
    private String targetParams = null;
96 97

  
97
	private CrsProj source = null;
98
    private CrsProj source = null;
98 99

  
99
	private CrsProj target = null;
100
    private CrsProj target = null;
100 101

  
101
	/**
102
	 * Constructor.
103
	 *
104
	 * @param from
105
	 *            CRS fuente.
106
	 * @param to
107
	 *            CRS destino.
108
	 * @throws CrsException
109
	 */
110
	public COperation(ICrs from, ICrs to) throws CrsException {
111
		sourceCrs = from;
112
		targetCrs = to;
113
		source = sourceCrs.getCrsProj();
114
		target = targetCrs.getCrsProj();
115
	}
102
    private CoordinateTransformation coordinateTransformation = null;
116 103

  
117
	/**
118
	 * Construcctor.
119
	 *
120
	 * @param sourceCrs
121
	 *            CRS fuente.
122
	 * @param targetCrs
123
	 *            CRS destino.
124
	 * @param sourceParams
125
	 *            Par?metros de transformaci?n para la fuente (en formato
126
	 *            proj4).
127
	 * @param targetParams
128
	 *            Par?metros de transformaci?n para el destino (en formato
129
	 *            proj4).
130
	 * @throws CrsException
131
	 */
132
	public COperation(ICrs sourceCrs, ICrs targetCrs, String sourceParams,
133
			String targetParams) throws CrsException {
134
		this.sourceCrs = sourceCrs;
135
		this.targetCrs = targetCrs;
136
		this.sourceParams = sourceParams;
137
		this.targetParams = targetParams;
104
    /**
105
     * Constructor.
106
     *
107
     * @param from
108
     *            CRS fuente.
109
     * @param to
110
     *            CRS destino.
111
     * @throws CrsException
112
     */
113
    public COperation(ICrs from, ICrs to) throws CrsException {
114
        sourceCrs = from;
115
        targetCrs = to;
116
        source = sourceCrs.getCrsProj();
117
        target = targetCrs.getCrsProj();
118
    }
138 119

  
139
		if (sourceParams != null)
140
			source = new CrsProj(sourceCrs.getProj4String() + sourceParams);
141
		else
142
			source = sourceCrs.getCrsProj();
143
		if (targetParams != null)
144
			target = new CrsProj(targetCrs.getProj4String() + targetParams);
145
		else
146
			target = targetCrs.getCrsProj();
147
	}
120
    /**
121
     * Construcctor.
122
     *
123
     * @param sourceCrs
124
     *            CRS fuente.
125
     * @param targetCrs
126
     *            CRS destino.
127
     * @param sourceParams
128
     *            Par?metros de transformaci?n para la fuente (en formato
129
     *            proj4).
130
     * @param targetParams
131
     *            Par?metros de transformaci?n para el destino (en formato
132
     *            proj4).
133
     * @throws CrsException
134
     */
135
    public COperation(ICrs sourceCrs, ICrs targetCrs, String sourceParams, String targetParams) throws CrsException {
136
        this.sourceCrs = sourceCrs;
137
        this.targetCrs = targetCrs;
138
        this.sourceParams = sourceParams;
139
        this.targetParams = targetParams;
148 140

  
149
	/**
150
	 * Realiza la operaci?n de transformaci?n sobre un punto. Si exiten
151
	 * par?metros de transformaci?n (<code>paramsCrsProj</code>) se utilizan en
152
	 * lugar del CRS fuente o destino, seg?n indique <code>paramsInTarget</code>
153
	 * .
154
	 *
155
	 * @throws OperationCrsException
156
	 *
157
	 */
158
	private Point2D operate(Point2D pt) throws CrsException,
159
			OperationCrsException {
160
		double x[] = { pt.getX() };
161
		double y[] = { pt.getY() };
162
		double z[] = { 0D };
163
		int errno = 0;
141
        if (sourceParams != null)
142
            source = new CrsProj(sourceCrs.getProj4String() + sourceParams);
143
        else
144
            source = sourceCrs.getCrsProj();
145
        if (targetParams != null)
146
            target = new CrsProj(targetCrs.getProj4String() + targetParams);
147
        else
148
            target = targetCrs.getCrsProj();
149
    }
164 150

  
165
		try {
166
			errno = JNIBaseCrs.operate(x, y, z, source, target);
167
		} catch (OperationCrsException e) {
168
			// Parche para arreglar posible error al transformar de latlong a proyectadas cuando la y es +/- 90
169
			if (e.getErrno() == -20) {
170
				source.reloadCrs();
171
				target.reloadCrs();
172
				if (!sourceCrs.isProjected() && targetCrs.isProjected()) {
173
					if (Math.abs((pt.getY() - 90.0)) < 0.000000001) {
174
						x[0] = pt.getX();
175
						y[0] = 89.99999999;
176
						z[0] = 0D;
177
						errno = JNIBaseCrs.operate(x, y, z, source, target);
178
					} else if (Math.abs(pt.getY() + 90.0) < 0.000000001) {
179
						x[0] = pt.getX();
180
						y[0] = -89.99999999;
181
						z[0] = 0D;
182
						errno = JNIBaseCrs.operate(x, y, z, source, target);
183
					}
184
				}
185
			}
186
		}
187
		if (errno != -38) // "failed to load NAD27-83 correction file"
188
							// (pj_strerrno.c)
189
			return new Point2D.Double(x[0], y[0]);
190
		else {
191
			x[0] = pt.getX();
192
			y[0] = pt.getY();
193
			z[0] = 0D;
194
			try {
195
				errno = JNIBaseCrs.operate(x, y, z, sourceCrs.getCrsProj(),
196
						targetCrs.getCrsProj());
197
			} catch (OperationCrsException e) {
198
				if (e.getErrno() == -20) {
199
					if (!sourceCrs.isProjected() && targetCrs.isProjected()) {
200
						if (Math.abs((pt.getY() - 90.0)) < 0.000000001) {
201
							x[0] = pt.getX();
202
							y[0] = 89.99999999;
203
							z[0] = 0D;
204
							errno = JNIBaseCrs.operate(x, y, z,
205
									sourceCrs.getCrsProj(),
206
									targetCrs.getCrsProj());
207
						} else if (Math.abs(pt.getY() + 90.0) < 0.000000001) {
208
							x[0] = pt.getX();
209
							y[0] = -89.99999999;
210
							z[0] = 0D;
211
							errno = JNIBaseCrs.operate(x, y, z,
212
									sourceCrs.getCrsProj(),
213
									targetCrs.getCrsProj());
214
						}
215
					}
216
				}
217
			}
218
			return new Point2D.Double(x[0], y[0]);
219
		}
151
    /**
152
     * Realiza la operaci?n de transformaci?n sobre un punto. Si exiten
153
     * par?metros de transformaci?n (<code>paramsCrsProj</code>) se utilizan en
154
     * lugar del CRS fuente o destino, seg?n indique <code>paramsInTarget</code>
155
     * .
156
     *
157
     * @throws OperationCrsException
158
     *
159
     */
160
    private Point2D operate(Point2D pt) throws CrsException, OperationCrsException {
161
        double x = pt.getX();
162
        double y = pt.getY();
220 163

  
221
		/*
222
		 * if (paramsCrsProj != null){ if (paramsInTarget) errno =
223
		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
224
		 * else errno = JNIBaseCrs.operate( x , y,
225
		 * z,paramsCrsProj,targetCrs.getCrsProj()); if (errno != -38) //
226
		 * "failed to load NAD27-83 correction file" (pj_strerrno.c) return new
227
		 * Point2D.Double(x[0],y[0]); }
228
		 *
229
		 * // Si el punto estaba fuera del ?mbito del nadgrid operamos sin
230
		 * nadgrid (convertimos) x[0] = pt.getX(); y[0] = pt.getY(); z[0] = 0D;
231
		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(),
232
		 * targetCrs.getCrsProj()); return new Point2D.Double(x[0],y[0]);
233
		 */
234
		// System.out.println("x="+x[0]+"y="+y[0]);
235
		// if(!targetCrs.isProjected())
236
		// return new Point2D.Double(x[0]*((180)/Math.PI),y[0]*((180)/Math.PI));
237
		// else
238
	}
164
        int errno = 0;
165
        String msg = "";
166
        int errtype = 0;
239 167

  
240
	/**
241
	 * Realiza la operaci?n de transformaci?n sobre un punto. Si exiten
242
	 * par?metros de transformaci?n (<code>paramsCrsProj</code>) se utilizan en
243
	 * lugar del CRS fuente o destino, seg?n indique <code>paramsInTarget</code>
244
	 * .
245
	 *
246
	 * @throws CrsException
247
	 *
248
	 */
249
	// TODO Eliminar este m?todo. Me vale con el operate(Point2D).
250
	private double[] operate(double[] ptOrig) throws OperationCrsException,
251
			CrsException {
252
		double x[] = { ptOrig[0] };
253
		double y[] = { ptOrig[1] };
254
		double z[] = { ptOrig[2] };
255
		int errno = 0;
168
        double[] transformed = { 0, 0, 0 };
169
        initializeCoordinateTransformation();
170
        if (coordinateTransformation != null) {
171
            transformed = coordinateTransformation.TransformPoint(x, y);
172
        }
256 173

  
257
		CrsProj source;
258
		CrsProj target;
259
		if (sourceParams != null)
260
			source = new CrsProj(sourceCrs.getProj4String() + sourceParams);
261
		else
262
			source = sourceCrs.getCrsProj();
263
		if (targetParams != null)
264
			target = new CrsProj(targetCrs.getProj4String() + targetParams);
265
		else
266
			target = targetCrs.getCrsProj();
174
        errno = gdal.GetLastErrorNo();
175
        msg = gdal.GetLastErrorMsg();
176
        errtype = gdal.GetLastErrorType();
267 177

  
268
		errno = JNIBaseCrs.operate(x, y, z, source, target);
269
		if (errno != -38) { // "failed to load NAD27-83 correction file"
270
							// (pj_strerrno.c)
271
			double ptDest[] = { x[0], y[0], z[0] };
272
			return ptDest;
273
		}
178
        Point2D.Double result = null;
179
        if (errno != 0 && errtype != 0) {
180
            //FIXME:
181
            // gdal no devuelve m?s de 20 errores por transformaci?n,
182
            // si queremos de los devuelva todos tenemos que anular la
183
            // transformaci?n cada vez que se produce un error
184
//            coordinateTransformation = null;
185
            // Adem?s, no podemos hacer nada por los puntos que devuelve
186
            // la transformaci?n cuando ha tenido un error.
187
            // Lo suyo ser?a elevar una excepci?n y quien la recoja que decida qu? dabe hacer con el punto,
188
            // por ejemplo, si se est? dibujando una geometr?a, tal vez, no habr?a que dibujarla o saltarse los
189
            // puntos que no se pueden transformar.
274 190

  
275
		/*
276
		 * if (paramsCrsProj != null){ if (paramsInTarget) errno =
277
		 * JNIBaseCrs.operate( x , y, z,sourceCrs.getCrsProj(), paramsCrsProj);
278
		 * else errno = JNIBaseCrs.operate( x , y,
279
		 * z,paramsCrsProj,targetCrs.getCrsProj()); if (errno != -38){ //
280
		 * "failed to load NAD27-83 correction file" (pj_strerrno.c) double
281
		 * ptDest[] = {x[0], y[0], z[0]}; return ptDest; } }
282
		 */
191
            gdal.ErrorReset();
283 192

  
284
		// Si el punto estaba fuera del ?mbito del nadgrid operamos sin nadgrid
285
		// (convertimos)
286
		x[0] = ptOrig[0];
287
		y[0] = ptOrig[1];
288
		z[0] = ptOrig[2];
289
		JNIBaseCrs.operate(x, y, z, sourceCrs.getCrsProj(),
290
				targetCrs.getCrsProj());
291
		double ptDest[] = { x[0], y[0], z[0] };
292
		return ptDest;
293
	}
193
        }
194
        result = new Point2D.Double(transformed[0], transformed[1]);
195
        return result;
196
    }
294 197

  
295
	public IProjection getPOrig() {
296
		return (IProjection) sourceCrs;
297
	}
198
    private void initializeCoordinateTransformation() {
199
        if (coordinateTransformation == null) {
200
            coordinateTransformation =
201
                CoordinateTransformation.CreateCoordinateTransformation(source.getSpatialReference(),
202
                    target.getSpatialReference());
203
        }
204
    }
298 205

  
299
	public IProjection getPDest() {
300
		return (IProjection) targetCrs;
301
	}
206
    public IProjection getPOrig() {
207
        return (IProjection) sourceCrs;
208
    }
302 209

  
303
	public Point2D convert(Point2D ptOrig, Point2D ptDest) {
304
		try {
305
			ptDest = operate(ptOrig);
306
		} catch (CrsException e) {
307
			logger.error("Can't operate over point orig (" + ptOrig.toString()
308
					+ ").", e);
309
			throw new IllegalStateException(e.getMessage());
310
		} catch (OperationCrsException e) {
311
			logger.error("Can't operate over point orig (" + ptOrig.toString()
312
					+ ").", e);
313
			throw new IllegalStateException(e.getMessage());
314
		}
315
		return ptDest;
316
	}
210
    public IProjection getPDest() {
211
        return (IProjection) targetCrs;
212
    }
317 213

  
318
	public Rectangle2D convert(Rectangle2D rect) {
319
		Point2D pt1 = new Point2D.Double(rect.getMinX(), rect.getMinY());
320
		Point2D pt2 = new Point2D.Double(rect.getMaxX(), rect.getMaxY());
321
		Point2D pt3 = new Point2D.Double(rect.getMinX(), rect.getMaxY());
322
		Point2D pt4 = new Point2D.Double(rect.getMaxX(), rect.getMinY());
323
		try {
324
			pt1 = operate(pt1);
325
			pt2 = operate(pt2);
326
			pt3 = operate(pt3);
327
			pt4 = operate(pt4);
328
		} catch (CrsException e) {
329
			logger.error("Can't operate over rect (" + rect.toString() + ").",
330
					e);
331
			throw new IllegalStateException(e.getMessage());
332
		} catch (OperationCrsException e) {
333
			logger.error("Can't operate over rect (" + rect.toString() + ").",
334
					e);
335
			throw new IllegalStateException(e.getMessage());
336
		}
214
    public Point2D convert(Point2D ptOrig, Point2D ptDest) {
215
        try {
216
            ptDest = operate(ptOrig);
217
        } catch (CrsException e) {
218
            logger.error("Can't operate over point orig (" + ptOrig.toString() + ").", e);
219
            throw new IllegalStateException(e.getMessage());
220
        } catch (OperationCrsException e) {
221
            logger.error("Can't operate over point orig (" + ptOrig.toString() + ").", e);
222
            throw new IllegalStateException(e.getMessage());
223
        }
224
        return ptDest;
225
    }
337 226

  
338
		double min_x = Math.min(Math.min(pt1.getX(), pt2.getX()),
339
				Math.min(pt3.getX(), pt4.getX()));
340
		double min_y = Math.min(Math.min(pt1.getY(), pt2.getY()),
341
				Math.min(pt3.getY(), pt4.getY()));
342
		double max_x = Math.max(Math.max(pt1.getX(), pt2.getX()),
343
				Math.max(pt3.getX(), pt4.getX()));
344
		double max_y = Math.max(Math.max(pt1.getY(), pt2.getY()),
345
				Math.max(pt3.getY(), pt4.getY()));
227
    public Rectangle2D convert(Rectangle2D rect) {
228
        Point2D pt1 = new Point2D.Double(rect.getMinX(), rect.getMinY());
229
        Point2D pt2 = new Point2D.Double(rect.getMaxX(), rect.getMaxY());
230
        Point2D pt3 = new Point2D.Double(rect.getMinX(), rect.getMaxY());
231
        Point2D pt4 = new Point2D.Double(rect.getMaxX(), rect.getMinY());
232
        try {
233
            pt1 = operate(pt1);
234
            pt2 = operate(pt2);
235
            pt3 = operate(pt3);
236
            pt4 = operate(pt4);
237
        } catch (CrsException e) {
238
            logger.error("Can't operate over rect (" + rect.toString() + ").", e);
239
            throw new IllegalStateException(e.getMessage());
240
        } catch (OperationCrsException e) {
241
            logger.error("Can't operate over rect (" + rect.toString() + ").", e);
242
            throw new IllegalStateException(e.getMessage());
243
        }
346 244

  
347
		return new Rectangle2D.Double(min_x, min_y, max_x - min_x, max_y
348
				- min_y);
349
	}
245
        double min_x = Math.min(Math.min(pt1.getX(), pt2.getX()), Math.min(pt3.getX(), pt4.getX()));
246
        double min_y = Math.min(Math.min(pt1.getY(), pt2.getY()), Math.min(pt3.getY(), pt4.getY()));
247
        double max_x = Math.max(Math.max(pt1.getX(), pt2.getX()), Math.max(pt3.getX(), pt4.getX()));
248
        double max_y = Math.max(Math.max(pt1.getY(), pt2.getY()), Math.max(pt3.getY(), pt4.getY()));
350 249

  
351
	public ICoordTrans getInverted() {
352
		COperation operation;
353
		try {
354
			operation = new COperation(targetCrs, sourceCrs, targetParams,
355
					sourceParams);
356
			return operation;
357
		} catch (CrsException e) {
358
			logger.error("Can't get operation.", e);
359
			return null;
360
		}
361
	}
362
	/*
363
	 * public void setParamsCrsProj(CrsProj paramsCrs, boolean inTarget){
364
	 * this.paramsInTarget = inTarget; this.paramsCrsProj = paramsCrs; }
365
	 */
250
        return new Rectangle2D.Double(min_x, min_y, max_x - min_x, max_y - min_y);
251
    }
252

  
253
    public ICoordTrans getInverted() {
254
        COperation operation;
255
        try {
256
            operation = new COperation(targetCrs, sourceCrs, targetParams, sourceParams);
257
            return operation;
258
        } catch (CrsException e) {
259
            logger.error("Can't get operation.", e);
260
            return null;
261
        }
262
    }
263
    /*
264
     * public void setParamsCrsProj(CrsProj paramsCrs, boolean inTarget){
265
     * this.paramsInTarget = inTarget; this.paramsCrsProj = paramsCrs; }
266
     */
366 267
}

Also available in: Unified diff