Statistics
| Revision:

root / trunk / extensions / extGeoreferencing / src / org / gvsig / georeferencing / GeoOperations.java @ 6214

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

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

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

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

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