Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoreferencing / src / org / gvsig / georeferencing / GeoOperations.java @ 8281

History | View | Annotate | Download (19.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.georeferencing;
20

    
21
import java.awt.geom.Point2D;
22
import java.io.BufferedOutputStream;
23
import java.io.BufferedReader;
24
import java.io.BufferedWriter;
25
import java.io.DataOutputStream;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.io.FileOutputStream;
30
import java.io.IOException;
31
import java.io.InputStreamReader;
32
import java.io.OutputStream;
33
import java.io.OutputStreamWriter;
34
import java.util.zip.DataFormatException;
35

    
36
import org.cresques.io.data.RasterMetaFileTags;
37
import org.gvsig.georeferencing.utils.AffineT;
38
import org.gvsig.georeferencing.utils.GeoUtils;
39
import org.gvsig.georeferencing.utils.PointT;
40
import org.xmlpull.v1.XmlPullParserException;
41
import org.xmlpull.v1.XmlPullParserFactory;
42
import org.xmlpull.v1.XmlSerializer;
43

    
44
import com.iver.cit.gvsig.fmap.layers.FLyrPoints;
45

    
46

    
47
/** 
48
 * Operaciones necesarias para la georreferenciaci?n a partir de la capa de puntos. 
49
 * En base a unos puntos de control de origen y otros de destino se crea una matriz
50
 * de transformaci?n para asignar la nueva posici?n a la imagen y crear ficheros 
51
 * de georreferenciaci?n en dos formatos: worldfile y rasterMetaFile
52
 * 
53
 * @author Nacho Brodin (brodin_ign@gva.es)
54
 */
55
public class GeoOperations{
56
        
57
        //**********************Vars**********************************
58
        private int                         order = 1;
59
        private PointT[]                 src = null;
60
        private PointT[]                 dst = null;
61
        private AffineT                affine = null;
62
        private boolean         createWorldFile = false;
63
        //**********************End Vars******************************
64
        
65
        //**********************Methods*******************************
66
        /**
67
         * Constructor
68
         */
69
        public GeoOperations(){}
70
        
71
        /**
72
         * Constructor. Crea las estructuras de puntos y calcula la transformaci?n af?n.
73
         * @param lyr
74
         */
75
        public GeoOperations(FLyrPoints lyr){
76
                FLyrPoints         lyrPoints = lyr;
77
                src = new PointT[lyr.getCountActivePoints()]; 
78
                dst = new PointT[lyr.getCountActivePoints()];
79
                int nPoint = 0;
80
                for(int i = 0; i<lyr.getCountPoints(); i++){
81
                        if(lyr.getPoint(i).active == true){
82
                                src[nPoint] = new PointT();
83
                                dst[nPoint] = new PointT();
84
                                src[nPoint].setX(lyr.getPoint(i).pixelPoint.getX());
85
                                src[nPoint].setY(lyr.getPoint(i).pixelPoint.getY());
86
                                src[nPoint].setI(lyr.getCountPoints());
87
                                dst[nPoint].setX(lyr.getPoint(i).mapPoint.getX());
88
                                dst[nPoint].setY(lyr.getPoint(i).mapPoint.getY());
89
                                dst[nPoint].setI(lyr.getCountPoints());
90
                                nPoint++;
91
                        }
92
                }
93
                
94
                if(lyr.getCountActivePoints() >= 3 * 10)
95
                        order = 3;
96
                else if(lyr.getCountActivePoints() >= 3 * 6)
97
                        order = 2;
98
                else
99
                        order = 1;
100

    
101
                affine = new AffineT();
102
                
103
                //Calcular la transformaci?n afin por m?nimos cuadrados
104
                affine = computeLeastSquaresAffine(affine, src, dst, order);
105
        }
106
        
107
        /**
108
         * A partir de la transformaci?n af?n creada en el construtor
109
         * genera un fichero de georreferenciaci?n para la imagen.
110
         * @param lyr                Capa de puntos
111
         * @param order        Orden del sistema de ecuaciones
112
         * @param widthPx        Ancho en pixeles de la imagen a georreferenciar
113
         * @param heightPx        Alto en pixeles de la imagen a georreferenciar
114
         * @param file                Nombre del fichero raster a georreferenciar
115
         */
116
        public void createGeorefFile(int widthPx, int heightPx, String file){
117
                try{
118
                        File f = new File(file);
119
                        String nameWorldFile = f.getPath().substring(0, f.getPath().lastIndexOf(".")) + GeoUtils.getWorldFileExtensionFromFileName(file);
120
                        if(createWorldFile)
121
                                createWorldFile(affine, widthPx, heightPx, nameWorldFile);
122
                        createRasterMetaFile(affine, widthPx, heightPx, nameWorldFile.substring(0, nameWorldFile.lastIndexOf("."))+".rmf");
123
                }catch(IOException ex){
124
                        System.err.println("Can't create WorldFile");
125
                }
126
        }
127
        
128
        /**
129
         * A partir de la transformaci?n af?n calculada en el contructor
130
         * transforma los puntos pasados como par?metros.
131
         * @param lyr                Capa de puntos
132
         * @param list                Lista de puntos a transformar
133
         * @return                  Lista de puntos transformados
134
         */
135
        public Point2D[] transformPoints(Point2D[] list){
136
                Point2D[] result = new Point2D[list.length];
137
                for(int i = 0; i < list.length;i++){
138
                        double[] pto = transformPoint((int)list[i].getX(), (int)list[i].getY(), affine);
139
                        result[i] = new Point2D.Double(pto[0], pto[1]);
140
                }
141
                return result;
142
        }
143
        
144
        /**
145
         * Crea un fichero de georreferenciaci?n (worldfile) a partir de la transformaci?n af?n. Para
146
         * esto necesita obtener las coordenadas reales de la coordenada en pixels (0,0) y calcular
147
         * el tama?o de pixel. 
148
         * @param affine                Transformaci?n
149
         * @param widthPx                Ancho en pixeles de la imagen a georreferenciar
150
         * @param heightPx                Alto en pixeles de la imagen a georreferenciar
151
         * @param nameWordlFile        Nombre del fichero de georreferenciaci?n
152
         * @throws IOException
153
         */
154
        private void createWorldFile(AffineT affine, int widthPx, int heightPx, String nameWordlFile) throws IOException {
155
                StringBuffer data = new StringBuffer();
156
                //double[] begin = transformPoint(0, 0, affine);
157
                //double[] end = transformPoint(widthPx, heightPx, affine);
158
                //double pixelSizeX = (end[0] - begin[0])/(widthPx - 1);
159
                //double pixelSizeY = (end[1] - begin[1])/(heightPx - 1);
160

    
161
                File f = new File(nameWordlFile);
162
                DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)) );
163
                
164
            data.append(affine.getCofX(1)+"\n");//pixelSizeX+"\n");
165
            data.append(affine.getCofX(2)+"\n");
166
            data.append(affine.getCofY(1)+"\n");
167
            data.append(affine.getCofY(2)+"\n");//(-1  * pixelSizeY)+"\n");
168
            data.append(affine.getCofX(0)+"\n");//""+begin[0]+"\n");
169
            data.append(affine.getCofY(0)+"\n");//""+end[1]+"\n");
170
            
171
            dos.writeBytes(data.toString());
172
                dos.close();
173
        }
174
        
175
        /**
176
         * A partir de XmlSerializer se salva la georreferenciaci?n 
177
         * @param serializer
178
         * @param min                
179
         * @param max                
180
         * @param widthPx                Ancho en pixeles de la imagen a georreferenciar
181
         * @param heightPx                Alto en pixeles de la imagen a georreferenciar
182
         * @throws IOException
183
         */
184
        private void serializeGeoreferencing(XmlSerializer serializer, double[] min, double[] max, int widthPx, int heightPx) throws IOException {                
185
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PROJ).text("Projection").endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PROJ).text("\n");
186
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.BBOX).text("\n");
187
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.POSX).text(""+affine.getCofX(0)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.POSX).text("\n");
188
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.POSY).text(""+affine.getCofY(0)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.POSY).text("\n");
189
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.ROTX).text(""+affine.getCofY(1)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.ROTX).text("\n");
190
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.ROTY).text(""+affine.getCofX(2)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.ROTY).text("\n");
191
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_SIZE_X).text(""+affine.getCofX(1)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_SIZE_X).text("\n");
192
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_SIZE_Y).text(""+ affine.getCofY(2)).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_SIZE_Y).text("\n");                
193
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.WIDTH).text(""+(max[0] - min[0])).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.WIDTH).text("\n");
194
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.HEIGHT).text(""+(max[1] - min[1])).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.HEIGHT).text("\n");
195
                serializer.endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.BBOX).text("\n");
196
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.DIM).text("\n");
197
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_WIDTH).text(""+widthPx).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_WIDTH).text("\n");
198
                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_HEIGHT).text(""+heightPx).endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.PX_HEIGHT).text("\n");
199
                serializer.endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.DIM).text("\n");
200
        }
201
        
202
        /**
203
         * Si ya existe un fichero de georreferenciaci?n se ha creado un fichero .tmp con
204
         * la nueva georreferenciaci?n. Esta funci?n mezcla este temporal con el .rmf existente
205
         * en un nuevo fichero _tmpOutput que ser? renombrado como el nuevo .rmf. Finalmente 
206
         * elimina el temporal y el _tmpOutput. 
207
         * @param fileName
208
         */
209
        private void mergeFiles(String fileName){
210
                try{
211
                        File rmfFile = new File(fileName);
212
                        File tmpFile = new File(fileName.substring(0, fileName.lastIndexOf("."))+".tmp");
213
                        File out = new File(rmfFile+"_tmpOutput");
214
                        
215
                        BufferedReader inRmf = new BufferedReader(new InputStreamReader(new FileInputStream(rmfFile)));
216
                        BufferedReader inTmp = new BufferedReader(new InputStreamReader(new FileInputStream(tmpFile)));
217
                        BufferedWriter outTmp = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out)));
218
                        
219
                        //Leemos el principio del .rmf
220
                String str = inRmf.readLine();
221
                while(!str.startsWith("<"+RasterMetaFileTags.MAIN_TAG)){
222
                        outTmp.write(str+"\n");
223
                        str = inRmf.readLine();
224
                }
225
                    outTmp.write(str+"\n");
226
                
227
                //Leemos la georreferenciaci?n del .tmp
228
                while(str != null && !str.startsWith("<"+RasterMetaFileTags.LAYER))
229
                        str = inTmp.readLine();
230
                while(str != null){
231
                        outTmp.write(str+"\n");
232
                        str = inTmp.readLine();
233
                }
234
                        
235
                //Saltamos la georreferenciaci?n que ya existia en el .rmf
236
                try{
237
                        str = inRmf.readLine();
238
                        while(str != null && 
239
                                  !str.startsWith("</"+RasterMetaFileTags.LAYER) &&
240
                                  !str.startsWith("<"+RasterMetaFileTags.GEOPOINTS) &&
241
                                  !str.startsWith("</"+RasterMetaFileTags.MAIN_TAG))
242
                                str = inRmf.readLine();
243
                }catch(Exception exc){
244
                        
245
                }
246
                
247
                //Leemos el resto del fichero .rmf
248
                if(!str.startsWith("<"+RasterMetaFileTags.GEOPOINTS))
249
                        str = inRmf.readLine();
250
                while(str != null){
251
                        outTmp.write(str+"\n");
252
                        str = inRmf.readLine();
253
                }
254
                
255
                outTmp.close();
256
                inRmf.close();
257
                inTmp.close();
258
                
259
                //Eliminamos el antiguo .rmf y lo sustituimos
260
                rmfFile.delete();
261
                out.renameTo(rmfFile);
262
                tmpFile.delete();
263
                
264
                }catch(FileNotFoundException exc){
265
                        
266
                }catch(IOException exc){
267
                        
268
                }
269
        }
270
        
271
        /**
272
         * Si no existe crea un fichero .rmf con la georreferenciaci?n de la imagen. Si existe este 
273
         * deber? a?adir o modificar la informaci?n de georreferenciaci?n en el fichero.
274
         * Para esto necesita obtener las coordenadas reales de la coordenada en pixels (0,0) y 
275
         * calcular el tama?o de pixel. 
276
         * @param affine                Transformaci?n
277
         * @param widthPx                Ancho en pixeles de la imagen a georreferenciar
278
         * @param heightPx                Alto en pixeles de la imagen a georreferenciar
279
         * @param nameWordlFile        Nombre del fichero de georreferenciaci?n
280
         * @throws IOException
281
         */
282
        private void createRasterMetaFile(AffineT affine, int widthPx, int heightPx, String nameWorldFile) throws IOException {
283
                File file = new File(nameWorldFile);
284
                double[] min = transformPoint(0, 0, affine);
285
                double[] max = transformPoint(widthPx, heightPx, affine);
286
                try{                
287
                        XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
288
                        XmlSerializer serializer = factory.newSerializer();
289
                        
290
                        if(file.exists()){
291
                                file = new File(nameWorldFile.substring(0, nameWorldFile.lastIndexOf("."))+".tmp");
292
                                serializer.setOutput(new FileOutputStream(file), null);
293
                                serializer.startDocument(null, null);
294
                                serializer.ignorableWhitespace("\n\n");
295
                                serializer.setPrefix("", RasterMetaFileTags.NAMESPACE);
296
                                serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.LAYER).text("\n");
297
                                serializeGeoreferencing(serializer, min, max, widthPx, heightPx);
298
                                serializer.endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.LAYER).text("\n");
299
                                serializer.endDocument();
300
                                mergeFiles(nameWorldFile);
301
                        }else{
302
                                        serializer.setOutput(new FileOutputStream(file), null);
303
                                        serializer.startDocument(null, null);
304
                                        serializer.ignorableWhitespace("\n\n");
305
                                        serializer.setPrefix("", RasterMetaFileTags.NAMESPACE);
306
                                        serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.MAIN_TAG).text("\n");
307
                                        serializer.startTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.LAYER).text("\n");
308
                                        serializeGeoreferencing(serializer, min, max, widthPx, heightPx);
309
                                        serializer.endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.LAYER).text("\n");
310
                                        serializer.endTag(RasterMetaFileTags.NAMESPACE, RasterMetaFileTags.MAIN_TAG).text("\n");
311
                                        serializer.endDocument();
312
                        }
313
                }catch(XmlPullParserException exc){}
314
        }
315
                
316
        /**
317
         * Calcula la transformaci?n af?n a partir de los puntos introducidos por el m?todo de 
318
         * m?nimos cuadrados.
319
         * @param af        Transformaci?n af?n
320
         * @param src        Puntos de entrada en coordenadas pixel
321
         * @param dst        Puntos de destino en coordenadas del mundo         
322
         * @param order        Orden del sistema de ecuaciones
323
         */
324
        public AffineT computeLeastSquaresAffine(AffineT af, PointT[] src, PointT[] dst, int order){
325
                double[] b = new double[dst.length];
326
                int i,cofs;
327

    
328
                af.setOrder(order);
329
                cofs = order <= 2 ? order*3 : 10;
330
                af.mallocCofs(cofs);
331
                
332
                //First compute the X cofs  
333
                for(i = 0; i < dst.length; i++) {    
334
                        b[i] = dst[i].getX();  
335
                }
336
                
337
                af.setCofX(singleLeastSquaresAffine(af.getXcofs(), src, b, order));
338
                
339
                //Now compute the Y cofs  
340
                for(i = 0; i < dst.length; i++) {    
341
                        b[i] = dst[i].getY();  
342
                }
343
                
344
                af.setCofY(singleLeastSquaresAffine(af.getYcofs(), src, b, order));
345
                
346
                return af;
347
        }
348
        
349
        private double[] singleLeastSquaresAffine(double[] a, PointT[] src, double[] dst, int order){
350
                int i,j;
351
                int n = dst.length;
352

    
353
                int points = order <= 2 ? order * 3 : 10;        
354
                double[][] combined = new double[points][points + 1];
355
                double[][] A = new double[n + 1][points];
356
                double[][] b = new double[n + 1][1];
357
                
358
                for(i = 0; i < n; i++) {
359
                        A[i][0] = 1.0;
360
                        A[i][1] = src[i].getX();
361
                        A[i][2] = src[i].getY();
362
                        if(order > 1) {
363
                                A[i][3] = src[i].getX() * src[i].getX();
364
                                A[i][4] = src[i].getX() * src[i].getY();
365
                                A[i][5] = src[i].getY() * src[i].getY();
366
                        }
367
                        if(order > 2) {
368
                                A[i][6] = src[i].getX() * src[i].getX() * src[i].getX();
369
                                A[i][7] = src[i].getX() * src[i].getX() * src[i].getY();
370
                                A[i][8] = src[i].getX() * src[i].getY() * src[i].getY();
371
                                A[i][9] = src[i].getY() * src[i].getY() * src[i].getY();
372
                        }
373
                        b[i][0] = dst[i];
374
                }
375
                
376
                double[][] Atrans = GeoUtils.transpose(A, n, points);
377
                double[][] left = GeoUtils.multmatrix(Atrans,A,points,n,points);
378
                double[][] right = GeoUtils.multmatrix(Atrans,b,points,n,1);
379
                
380
                for(i = 0; i < points; i++) {
381
                        combined[i][0] = right[i][0];
382
                        for(j = 0; j < points; j++) {
383
                                combined[i][j+1] = left[i][j];
384
                        }
385
                }
386
                
387
                try{
388
                        combined = solve(combined, points, points+1);
389
                }catch(DataFormatException ex){
390
                        System.err.println("Can't solve matrix");
391
                }
392

    
393
                for(i = 0; i < points; i++) {
394
                        a[i] = combined[i][0];
395
                }
396
                return a;
397
        }
398
        
399
        
400
        private double[][] solve(double[][] mat,int rows,int cols)throws DataFormatException{
401
                int i,j,k;
402
                double d,tmp;
403
                int big;
404

    
405
                for(i = 0; i < rows; i++) {
406
                        // Find largest row
407
                                big = i;
408
                                for(j = i; j < rows; j++) {
409
                                        if(Math.abs(mat[j][i+1]) > Math.abs(mat[big][i+1])) {
410
                                                big = j;
411
                                        }
412
                                }
413
                                // swap row i and row big
414
                                for(k = 0; k < cols ; k++) {
415
                                        tmp = mat[i][k];
416
                                        mat[i][k] = mat[big][k];
417
                                        mat[big][k] = tmp;
418
                                }
419
                        if(mat[i][i+1] == 0) 
420
                                throw new DataFormatException();
421
                        
422
                        d = 1.0 / mat[i][i+1]; 
423
                        for(j = 0; j < cols ; j++) {
424
                                mat[i][j] *= d;
425
                                //assert(!isnan(mat[i][j]));
426
                        }
427
                        for(k = 0; k < rows; k++) {
428
                                if(k == i)
429
                                        continue;
430
                                if(mat[k][i+1] != 0.0) {
431
                                d = mat[k][i+1] / mat[i][i+1]; 
432
                                        for(j = 0; j < cols ; j++) {
433
                                                mat[k][j] -= d*mat[i][j];
434
                                                //assert(!isnan(mat[k][j]));
435
                                        }
436
                                }
437
                        }
438
                }
439
                return mat;
440
        }
441
        
442
        /**
443
         * Obtiene las coordenadas de un punto en coordenadas del mundo a partir de una transformaci?n 
444
         * y el punto de entrada en coordenadas de la imagen.
445
         * @param sx        Coordenada X del punto de entrada 
446
         * @param syz        Coordenada Y del punto de entrada
447
         * @param af        Transformaci?n
448
         * @return                Punto transformado
449
         */
450
        public double[] transformPoint(int sx, int sy, AffineT af){
451
                double[] p = new double[2];
452
                if(af.getOrder() == 1) {
453
                        p[0] = af.getCofX(0) + af.getCofX(1) * sx + af.getCofX(2) * sy;
454
                        p[1] = af.getCofY(0) + af.getCofY(1) * sx + af.getCofY(2) * sy;
455
                }
456
                else if(af.getOrder() == 2) {
457
                        p = quadTransformPoint(sx, sy, af);
458
                }
459
                else {
460
                        p = cubicTransformPoint(sx, sy, af);
461
                 }
462
                return p;
463
        }
464
        
465
        private static double[] quadTransformPoint(int sx, int sy, AffineT af){
466
                double[] p = new double[2];
467
                p[0] = af.getCofX(0) + af.getCofX(1) * sx + af.getCofX(2) * sy + 
468
                        af.getCofX(3) * sx * sx + af.getCofX(4) * sx * sy + af.getCofX(5) * sy * sy;
469
                p[1] = af.getCofY(0) + af.getCofY(1) * sx + af.getCofY(2) * sy + 
470
                        af.getCofY(3) * sx * sx + af.getCofY(4) * sx * sy + af.getCofY(5) * sy * sy;
471
                return p;
472
        }
473
        
474
        private static double[] cubicTransformPoint(int sx, int sy, AffineT af){
475
                double[] p = new double[2];
476
                p[0] = af.getCofX(0) + af.getCofX(1) * sx + af.getCofX(2) * sy + 
477
                        af.getCofX(3) * sx * sx + af.getCofX(4) * sx * sy + af.getCofX(5) * sy * sy +
478
                        af.getCofX(6) * sx * sx * sx + af.getCofX(7) * sx * sx * sy +
479
                        af.getCofX(8)*sx*sy*sy + af.getCofX(9)*sy*sy*sy;
480
                p[1] = af.getCofY(0) + af.getCofY(1) * sx + af.getCofY(2) * sy + 
481
                        af.getCofY(3) * sx * sx + af.getCofY(4) * sx * sy + af.getCofY(5) * sy * sy +
482
                        af.getCofY(6) * sx * sx * sx + af.getCofY(7) * sx * sx * sy +
483
                        af.getCofY(8) * sx * sy * sy + af.getCofY(9) * sy * sy * sy;
484
                return p;
485
        }        
486
        //**********************End Methods***************************
487
        
488
        //**********************Setters & Getters*********************
489
        /**
490
         * M?todo para notificar si se desea crear o no el fichero de coordenadas .tfw, .wld .jpgw ,... 
491
         * @param createWorldFile
492
         */
493
        public void setCreateWorldFile(boolean createWorldFile) {
494
                this.createWorldFile = createWorldFile;
495
        }
496
        
497
        /**
498
         * Obtiene la extensi?n del fichero de georreferenciaci?n
499
         * @return String con la extensi?n del fichero de georreferenciaci?n dependiendo
500
         * del valor del formato obtenido del servidor. Por defecto asignaremos un .wld 
501
         */
502
        /*private String getExtensionWorldFile(String file){
503
                String ext = file.substring(file.lastIndexOf(".") + 1).toLowerCase();
504
                String extWorldFile = ".wld";
505
            if(ext.equals("tif") || ext.equals("tiff"))
506
                    extWorldFile = ".tfw";
507
            if(ext.equals("jpeg") || ext.equals("jpg"))
508
                    extWorldFile = ".jgw";
509
            if(ext.equals("gif"))
510
                    extWorldFile = ".gfw";
511
            if(ext.equals("png"))
512
                    extWorldFile = ".pgw";
513
            return extWorldFile;
514
        }*/
515
        
516
        /**
517
         * Obtiene la matriz de transformaci?n
518
         * @return AffineT
519
         */
520
        public AffineT getAffine() {
521
                return affine;
522
        }
523
        //**********************End Setters & Getters*****************
524
        
525
}