Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1010 / libraries / libCq_CMS_praster / src / org / cresques / px / PxRaster.java @ 12804

History | View | Annotate | Download (59.2 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 * cresques@gmail.com
23
 */
24
package org.cresques.px;
25

    
26
import java.awt.Color;
27
import java.awt.Component;
28
import java.awt.Graphics2D;
29
import java.awt.Image;
30
import java.awt.geom.AffineTransform;
31
import java.awt.geom.GeneralPath;
32
import java.awt.geom.NoninvertibleTransformException;
33
import java.awt.geom.Point2D;
34
import java.awt.image.BufferedImage;
35
import java.awt.image.DataBuffer;
36
import java.awt.image.ImageObserver;
37
import java.io.File;
38
import java.util.ArrayList;
39
import java.util.Date;
40
import java.util.Vector;
41

    
42
import org.cresques.cts.ICoordTrans;
43
import org.cresques.cts.IProjection;
44
import org.cresques.filter.RasterFilterStack;
45
import org.cresques.filter.RasterFilterStackManager;
46
import org.cresques.filter.bands.PaletteFilter;
47
import org.cresques.filter.bands.PaletteStackManager;
48
import org.cresques.filter.bands.RasterByteToImageFilter;
49
import org.cresques.filter.bands.RasterDoubleToImageFilter;
50
import org.cresques.filter.bands.RasterFloatToImageFilter;
51
import org.cresques.filter.bands.RasterIntToImageFilter;
52
import org.cresques.filter.bands.RasterShortToImageFilter;
53
import org.cresques.filter.bands.RasterToImageFilter;
54
import org.cresques.filter.enhancement.TransparencyRange;
55
import org.cresques.geo.Projected;
56
import org.cresques.geo.ViewPortData;
57
import org.cresques.io.EcwFile;
58
import org.cresques.io.GdalFile;
59
import org.cresques.io.GeoRasterFile;
60
import org.cresques.io.MemoryRasterDriver;
61
import org.cresques.io.data.RasterBuf;
62
import org.cresques.io.datastruct.Statistic;
63
import org.cresques.io.exceptions.SupersamplingNotSupportedException;
64

    
65

    
66
/**
67
 *
68
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
69
 * @author Nacho Brodin (brodin_ign@gva.es)
70
 *
71
 */
72
public class PxRaster extends PxObj implements Projected {
73
    protected GeoRasterFile[] geoFile = null;
74
    protected ImageObserver component = null;
75
    Vector pts = null;
76

    
77
    // Soporte para n bandas, visibles de 3 en 3, en ficheros separados
78
    //protected GeoRasterFile [] colorBand = null;
79
    protected int rBand = 1;
80

    
81
    // Soporte para n bandas, visibles de 3 en 3, en ficheros separados
82
    //protected GeoRasterFile [] colorBand = null;
83
    protected int gBand = 2;
84

    
85
    // Soporte para n bandas, visibles de 3 en 3, en ficheros separados
86
    //protected GeoRasterFile [] colorBand = null;
87
    protected int bBand = 3;
88
    public Statistic stats = new Statistic();
89
    int transparente = 0x10ffff80;
90
    String vName = null;
91
    protected boolean pintaMarco = false; //true;
92
    IProjection proj = null;
93
    protected Extent extentOrig = null;
94
    ICoordTrans rp = null;
95
    public RasterFilterStack filterStack = new RasterFilterStack(stats);
96
    private BandSwitch bandSwitch = new BandSwitch();
97
    private boolean firstPxRaster = true;
98
    private final double percentFilterInit = 0.02;
99
    private RasterFilterStackManager stackManager = null;
100
    private Image geoImage = null;
101
    private ViewPortData lastViewPort = null;
102

    
103
    /**
104
     * Variable usada por el draw para calcular el n?mero de pixeles a leer de un
105
     * raster rotado. 
106
     */
107
    private double[] adjustedRotedExtent = null;
108
    
109
    /**
110
     * Constructor.
111
     * @param component
112
     */
113
    public PxRaster(ImageObserver component) {
114
        this.component = component;
115
    }
116

    
117
    /**
118
     * Contructor para un solo fichero
119
     * @param proj        Proyeccci?n
120
     * @param fname Nombre del fichero
121
     * @param component
122
     */
123
    public PxRaster(IProjection proj, String fname, ImageObserver component) {
124
        geoFile = new GeoRasterFile[1];
125
        geoFile[0] = GeoRasterFile.openFile(proj, fname); //loadECW(fname);
126
        geoFile[0].setUpdatable((Component) component);
127
        this.proj = proj;
128
        this.component = component;
129
        setExtent(geoFile[0].getExtent());
130
        setExtentForRequest(geoFile[0].getExtentForRequest());
131
        geoFile[0].setView(geoFile[0].getExtent());
132
        extentOrig = extent;
133
        bandSwitch.addFile(geoFile[0]);
134

    
135
        if (geoFile[0].getBandCount() >= 3) {
136
            setBand(GeoRasterFile.RED_BAND, 0);
137
            setBand(GeoRasterFile.GREEN_BAND, 1);
138
            setBand(GeoRasterFile.BLUE_BAND, 2);
139
        } else if (geoFile[0].getBandCount() == 2) {
140
            setBand(GeoRasterFile.RED_BAND, 0);
141
            setBand(GeoRasterFile.GREEN_BAND, 1);
142
            setBand(GeoRasterFile.BLUE_BAND, 1);
143
        } else if (geoFile[0].getBandCount() == 1) {
144
            //setBand(GeoRasterFile.RED_BAND|GeoRasterFile.GREEN_BAND|GeoRasterFile.BLUE_BAND, 0);
145
            setBand(GeoRasterFile.RED_BAND, 0);
146
            setBand(GeoRasterFile.GREEN_BAND, 0);
147
            setBand(GeoRasterFile.BLUE_BAND, 0);
148
        }
149
    }
150

    
151
    /**
152
     * Constructor para multiples ficheros
153
     */
154
    public PxRaster(IProjection proj, String[] fnames, ImageObserver component) {
155
        this.proj = proj;
156
        this.component = component;
157
        geoFile = new GeoRasterFile[fnames.length];
158

    
159
        for (int i = 0; i < geoFile.length; i++) {
160
            geoFile[i] = GeoRasterFile.openFile(proj, fnames[i]); //loadECW(fname);
161
            geoFile[i].setUpdatable((Component) component);
162
            setExtent(geoFile[i].getExtent());
163
            setExtentForRequest(geoFile[i].getExtentForRequest());
164
            geoFile[i].setView(geoFile[i].getExtent());
165
            bandSwitch.addFile(geoFile[i]);
166
        }
167

    
168
        //geoFile = geoFile[0];
169
        extentOrig = extent;
170

    
171
        if ((fnames.length >= 3) || (geoFile[0].getBandCount() > 2)) {
172
            setBand(GeoRasterFile.RED_BAND, 0);
173
            setBand(GeoRasterFile.GREEN_BAND, 1);
174
            setBand(GeoRasterFile.BLUE_BAND, 2);
175
        } else {
176
            setBand(GeoRasterFile.RED_BAND | GeoRasterFile.GREEN_BAND |
177
                    GeoRasterFile.BLUE_BAND, 0);
178
        }
179
    }
180

    
181
    public PxRaster(GeoRasterFile eFile, ImageObserver component, Extent view) {
182
        geoFile = new GeoRasterFile[1];
183
        geoFile[0] = eFile; //loadECW(fname);
184
        geoFile[0].setUpdatable((Component) component);
185
        setProjection(geoFile[0].getProjection());
186
        this.component = component;
187

    
188
        setExtent(geoFile[0].getExtent());
189
        setExtentForRequest(geoFile[0].getExtentForRequest());
190
        if(view != null){
191
                geoFile[0].setView(view); //geoFile.getExtent());
192
                extentOrig = extent;
193
                bandSwitch.addFile(eFile);
194
        
195
                if (geoFile[0].getBandCount() >= 3) {
196
                    setBand(GeoRasterFile.RED_BAND, 0);
197
                    setBand(GeoRasterFile.GREEN_BAND, 1);
198
                    setBand(GeoRasterFile.BLUE_BAND, 2);
199
                } else if (geoFile[0].getBandCount() == 2) {
200
                    setBand(GeoRasterFile.RED_BAND, 0);
201
                    setBand(GeoRasterFile.GREEN_BAND, 1);
202
                    setBand(GeoRasterFile.BLUE_BAND, 1);
203
                } else if (geoFile[0].getBandCount() == 1) {
204
                    //setBand(GeoRasterFile.RED_BAND|GeoRasterFile.GREEN_BAND|GeoRasterFile.BLUE_BAND, 0);
205
                    setBand(GeoRasterFile.RED_BAND, 0);
206
                    setBand(GeoRasterFile.GREEN_BAND, 0);
207
                    setBand(GeoRasterFile.BLUE_BAND, 0);
208
                }
209
        }
210
    }
211

    
212
    /**
213
     * A?ade un GeoRasterFile al PxRaster
214
     * @param fileName Nombre del fichero
215
     */
216
    public GeoRasterFile addFile(String fileName) {
217
        if (geoFile != null) {
218
            GeoRasterFile[] listFiles = new GeoRasterFile[geoFile.length + 1];
219

    
220
            for (int i = 0; i < geoFile.length; i++)
221
                listFiles[i] = geoFile[i];
222

    
223
            listFiles[geoFile.length] = GeoRasterFile.openFile(proj, fileName);
224
            listFiles[geoFile.length].setUpdatable((Component) component);
225
            setExtent(listFiles[geoFile.length].getExtent());
226
            setExtentForRequest(listFiles[geoFile.length].getExtentForRequest());
227
            listFiles[geoFile.length].setView(listFiles[geoFile.length].getExtent());
228
            bandSwitch.addFile(listFiles[geoFile.length]);
229
            geoFile = listFiles;
230
            return listFiles[geoFile.length - 1];
231
        } else {
232
            System.err.println("PxRaster.addFile(): Imagen no cargada.");
233
            return null;
234
        }
235
    }
236

    
237
    /**
238
     * Devuelve el Extent de un fichero son necesidad de a?adirlo
239
     * al PxRaster
240
     * @param fileName
241
     * @return
242
     */
243
    public Extent testExtentFile(String fileName) {
244
        GeoRasterFile grf = GeoRasterFile.openFile(proj, fileName);
245

    
246
        return grf.getExtent();
247
    }
248

    
249
    /**
250
     * Obtiene el valor del pixel del Image en la posici?n wcx,wcy
251
     * @param wcx Posici?n x
252
     * @param wcx Posici?n y
253
     * @return valor de pixel
254
     */
255
    public int[] getPixel(double wcx, double wcy) {
256
        if (geoImage != null) {
257
            int ptox = 0;
258
            int ptoy = 0;
259

    
260
            try {
261
                //Extent de la imagen completa
262
                Extent extOrtofoto = geoFile[0].getExtent();
263

    
264
                //Variables q definen el extent del objeto image
265
                double minx = 0;
266

    
267
                //Variables q definen el extent del objeto image
268
                double miny = 0;
269

    
270
                //Variables q definen el extent del objeto image
271
                double maxx = 0;
272

    
273
                //Variables q definen el extent del objeto image
274
                double maxy = 0;
275

    
276
                if (lastViewPort.getExtent().getMin().getX() < extOrtofoto.minX()) {
277
                    minx = extOrtofoto.minX();
278
                } else {
279
                    minx = lastViewPort.getExtent().getMin().getX();
280
                }
281

    
282
                if (lastViewPort.getExtent().getMax().getX() > extOrtofoto.maxX()) {
283
                    maxx = extOrtofoto.maxX();
284
                } else {
285
                    maxx = lastViewPort.getExtent().getMax().getX();
286
                }
287

    
288
                if (lastViewPort.getExtent().getMin().getY() < extOrtofoto.minY()) {
289
                    miny = extOrtofoto.minY();
290
                } else {
291
                    miny = lastViewPort.getExtent().getMin().getY();
292
                }
293

    
294
                if (lastViewPort.getExtent().getMax().getY() > extOrtofoto.maxY()) {
295
                    maxy = extOrtofoto.maxY();
296
                } else {
297
                    maxy = lastViewPort.getExtent().getMax().getY();
298
                }
299

    
300
                //Comprobamos que estemos dentro del extent del Image
301
                if ((wcx < minx) || (wcx > maxx) || (wcy < miny) ||
302
                        (wcy > maxy)) {
303
                    int[] res = { -1, -1, -1, -1 };
304

    
305
                    return res;
306
                }
307

    
308
                //Pasamos a coordenadas del Image las coordenadas del mundo real
309
                int w = ((BufferedImage) geoImage).getWidth();
310
                int h = ((BufferedImage) geoImage).getHeight();
311
                double wcw = maxx - minx;
312
                double wch = maxy - miny;
313
                ptox = (int) (((wcx - minx) * w) / wcw);
314
                ptoy = (int) (((wcy - miny) * h) / wch);
315

    
316
                //Obtenemos el pto seleccionado del Image y extraemos el RGB
317
                int px = ((BufferedImage) geoImage).getRGB(ptox, h - ptoy);
318
                int[] values = new int[4];
319
                values[0] = ((px & 0xff000000) >> 24);
320
                values[1] = ((px & 0x00ff0000) >> 16);
321
                values[2] = ((px & 0x0000ff00) >> 8);
322
                values[3] = (px & 0x000000ff);
323

    
324
                return values;
325
            } catch (ArrayIndexOutOfBoundsException e) {
326
                e.printStackTrace();
327
            }
328
        }
329

    
330
        return null;
331
    }
332

    
333
    /**
334
     * Elimina un GeoRasterFile al PxRaster
335
     * @param finaName Nombre del fichero
336
     */
337
    public GeoRasterFile delFile(String fileName) {
338
        if (geoFile != null) {
339
            Vector grfTemp = new Vector();
340

    
341
            GeoRasterFile grfDelete = null;
342
            
343
            for (int i = 0; i < geoFile.length; i++) {
344
                if (!fileName.endsWith(geoFile[i].getName())) {
345
                    grfTemp.add(geoFile[i]);
346
                }else
347
                        grfDelete = geoFile[i];
348
            }
349

    
350
            GeoRasterFile[] listFiles = new GeoRasterFile[grfTemp.size()];
351

    
352
            for (int i = 0; i < listFiles.length; i++)
353
                listFiles[i] = (GeoRasterFile) grfTemp.get(i);
354

    
355
            //Lo eliminamos del bandSwitch
356
            for (int i = 0; i < geoFile.length; i++) {
357
                if (fileName.endsWith(geoFile[i].getName())) {
358
                    bandSwitch.removeFile(geoFile[i]);
359
                }
360
            }
361

    
362
            geoFile = listFiles;
363
            return grfDelete;
364
        } else {
365
            System.err.println("PxRaster.addFile(): Imagen no cargada.");
366
            return null;
367
        }
368
    }
369

    
370
    /**
371
     * Obtiene el tama?o de bloque
372
     * @return
373
     */
374
    public int getBlockSize() {
375
        return geoFile[0].getBlockSize();
376
    }
377

    
378
    /**
379
     *
380
     * @return
381
     */
382
    public GeoRasterFile[] getGeoFiles() {
383
        return geoFile;
384
    }
385

    
386
    public GeoRasterFile getGeoFile() {
387
        return geoFile[0];
388
    }
389

    
390
    /**
391
     * Obtiene el n?mero de bandas del PxRaster. Si ls longitud de geoFile es 1 quiere
392
     * decir que hay un solo fichero que contiene todas las bandas. Si hay m?s de un geoFile
393
     * el n?mero de bandas ser? la suma de todas las bandas de las im?genes que forman
394
     * el geoFile
395
     * @return N?mero de bandas
396
     */
397
    public int getBandCount() {
398
        return bandSwitch.getBandCount();
399
    }
400

    
401
    /**
402
     * Obtiene el tipo de dato del primer GeoRasterFile
403
     * @return
404
     */
405
    public int getDataType() {
406
        if (geoFile != null) {
407
            return geoFile[0].getDataType();
408
        } else {
409
            System.err.println("PxRaster.getDataType(): Imagen no cargada.");
410
        }
411

    
412
        return 0;
413
    }
414

    
415
    /**
416
     * Obtiene el vector de GeoRasterFile que componen el PxRaster
417
     * @return vector GeoRasterFile
418
     */
419
    public GeoRasterFile[] getFiles() {
420
        return geoFile;
421
    }
422

    
423
    /**
424
     * Asocia un colorBand al rojo, verde o azul.
425
     * @param flag cual (o cuales) de las bandas.
426
     * @param nBand        que colorBand
427
     */
428
    public void setBand(int flag, int nBand) {
429
        bandSwitch.setBand(flag, nBand);
430
    }
431

    
432
    /**
433
     * Obtiene la posici?n del fichero asignado a la banda
434
     * que se le pasa por par?metro
435
     * @return
436
     */
437
    public int getPosFile(int flag) {
438
        if (flag == GeoRasterFile.RED_BAND) {
439
            return bandSwitch.getBandR().getPos();
440
        } else if (flag == GeoRasterFile.GREEN_BAND) {
441
            return bandSwitch.getBandG().getPos();
442
        } else if (flag == GeoRasterFile.BLUE_BAND) {
443
            return bandSwitch.getBandB().getPos();
444
        } else {
445
            return -1;
446
        }
447
    }
448

    
449
    /**
450
     * Devuelve el colorBand activo en la banda especificada.
451
     * @param flag banda.
452
     */
453
    public int getBand(int flag) {
454
        if (flag == GeoRasterFile.RED_BAND) {
455
            return bandSwitch.getBandR().getBand();
456
        } else if (flag == GeoRasterFile.GREEN_BAND) {
457
            return bandSwitch.getBandG().getBand();
458
        } else if (flag == GeoRasterFile.BLUE_BAND) {
459
            return bandSwitch.getBandB().getBand();
460
        } else {
461
            return -1;
462
        }
463
    }
464

    
465
    /**
466
     * @param pm
467
     */
468
    public void setDrawBorder(boolean pm) {
469
        pintaMarco = pm;
470
    }
471

    
472
    /**
473
     * Obtiene el nombre del fichero si solo hay uno
474
     * @return Nombre del fichero
475
     */
476
    public String getFName() {
477
        return geoFile[0].getName();
478
    }
479

    
480
    /**
481
     * Obtiene el nombre del fichero GeoRasterFile seleccionado
482
     * @param i        posici?n del GeoRasterFile
483
     * @return Nombre del fichero
484
     */
485
    public String getFName(int i) {
486
        if (geoFile != null) {
487
            if (i < geoFile.length) {
488
                return geoFile[i].getName();
489
            } else {
490
                return null;
491
            }
492
        } else {
493
            System.err.println("PxRaster.getFName(): Imagen no cargada.");
494

    
495
            return null;
496
        }
497
    }
498

    
499
    /**
500
     * Obtiene una lista de Strings con los nombres de todos los ficheros
501
     * que tiene el PxRaster
502
     * @return Lista de nombres
503
     */
504
    public String[] getLisName() {
505
        if (geoFile != null) {
506
            String[] list = new String[geoFile.length];
507

    
508
            for (int i = 0; i < geoFile.length; i++)
509
                list[i] = geoFile[i].getName();
510

    
511
            return list;
512
        } else {
513
            System.err.println("PxRaster.getListName(): Imagen no cargada.");
514

    
515
            return null;
516
        }
517
    }
518

    
519
    /**
520
     * Devuelve la anchura total del fichero, en pixeles.
521
     * @return ancho en pixeles
522
     */
523
    public int getFWidth() {
524
        if (geoFile != null) {
525
            return geoFile[0].getWidth();
526
        } else {
527
            System.err.println("PxRaster.getFWidth(): Imagen no cargada.");
528

    
529
            return 0;
530
        }
531
    }
532

    
533
    /**
534
     * Devuelve la anchura total del fichero, en pixeles.
535
     * @return ancho en pixeles
536
     */
537
    public int getFWidth(int i) {
538
        if (i < geoFile.length) {
539
            return geoFile[i].getWidth();
540
        } else {
541
            System.err.println("PxRaster.getFWidth(): Imagen no cargada.");
542

    
543
            return 0;
544
        }
545
    }
546

    
547
    /**
548
     * Devuelve la altura total del fichero, en pixeles.
549
     * @return alto en pixeles
550
     */
551
    public int getFHeight() {
552
        if (geoFile != null) {
553
            return geoFile[0].getHeight();
554
        } else {
555
            System.err.println("PxRaster.getFHeight(): Imagen no cargada.");
556

    
557
            return 0;
558
        }
559
    }
560

    
561
    /**
562
     * Devuelve la altura total del fichero, en pixeles.
563
     * @return alto en pixeles
564
     */
565
    public int getFHeight(int i) {
566
        if (i < geoFile.length) {
567
            return geoFile[i].getHeight();
568
        } else {
569
            System.err.println("PxRaster.getFHeight(): Imagen no cargada.");
570

    
571
            return 0;
572
        }
573
    }
574

    
575
    /**
576
     * Devuelve el n?mero de ficheros que componen el PxRaster
577
     * @return N?mero de ficheros
578
     */
579
    public int nFiles() {
580
        if (geoFile != null) {
581
            return geoFile.length;
582
        } else {
583
            return 0;
584
        }
585
    }
586

    
587
    /**
588
     * Activa o desactiva la transparencia de los ficheros que forman el PxRaster
589
     * @param t true o false para activar o desactivar transparencia
590
     */
591
    public void setTransparency(boolean t) {
592
        if (geoFile != null) {
593
            for (int i = 0; i < geoFile.length; i++) {
594
                geoFile[i].setTransparency(t);
595
            }
596
        } else {
597
            System.err.println("PxRaster.setTransparency(): Imagen no cargada.");
598

    
599
            return;
600
        }
601
    }
602

    
603
    /**
604
     * Pone la transparencia de los ficheros de la imagen a un valor
605
     * @param t Valor para la transparencia
606
     */
607
    public void setTransparency(int t) {
608
        if (geoFile != null) {
609
            for (int i = 0; i < geoFile.length; i++) {
610
                geoFile[i].setTransparency(t);
611
            }
612
        } else {
613
            System.err.println("PxRaster.setTransparency(): Imagen no cargada.");
614

    
615
            return;
616
        }
617
    }
618

    
619
    /**
620
     * Obtiene el alpha del primer fichero. Han de ser iguales en todos
621
     * los ficheros de la imagen.
622
     * @return alpha
623
     */
624
    public int getAlpha() {
625
        if (geoFile != null) {
626
            return geoFile[0].getAlpha();
627
        } else {
628
            System.err.println("PxRaster.getAlpha(): Imagen no cargada.");
629

    
630
            return 0;
631
        }
632
    }
633

    
634
    /**
635
     * Asigna el extent completo del raster. Este contiene las coordenadas reales tanto
636
     * para un raster rotado como sin rotar. Este extent coincide con requestExtent
637
     * cuando el raster no tiene rotaci?n.
638
     * @param Extent 
639
     */
640
    public void setExtent(Extent e) {
641
        super.extent = e;
642
        if(e != null && proj != null){
643
                pts = new Vector();
644
                pts.add(proj.createPoint(e.minX(), e.minY()));
645
                pts.add(proj.createPoint(e.maxX(), e.minY()));
646
                pts.add(proj.createPoint(e.maxX(), e.maxY()));
647
                pts.add(proj.createPoint(e.minX(), e.maxY()));
648
        }
649
    }
650
    
651
    /**
652
     * Asigna el extent sobre el que se ajusta una petici?n para que esta no exceda el 
653
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
654
     * pero para un raster rotado ser? igual al extent del raster como si no 
655
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
656
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
657
     * aplicado.
658
     * @param Extent
659
     */
660
    public void setExtentForRequest(Extent e) {
661
        super.requestExtent = e;
662
        if(e != null && proj != null){
663
                pts = new Vector();
664
                pts.add(proj.createPoint(e.minX(), e.minY()));
665
                pts.add(proj.createPoint(e.maxX(), e.minY()));
666
                pts.add(proj.createPoint(e.maxX(), e.maxY()));
667
                pts.add(proj.createPoint(e.minX(), e.maxY()));
668
        }
669
    }
670

    
671
    /**
672
     * Cambia la vista (viewport) sobre el raster.
673
     *
674
     * @param v extent
675
     * @param vName nombre
676
     */
677
    public void setView(Extent v, String vName) {
678
        if (geoFile != null) {
679
            for (int i = 0; i < geoFile.length; i++) {
680
                geoFile[i].setView(v);
681
            }
682
        } else {
683
            System.err.println("PxRaster.setView(): Imagen no cargada.");
684

    
685
            return;
686
        }
687

    
688
        this.vName = vName;
689
    }
690

    
691
    /**
692
     * Obtiene la escala.
693
     *
694
     * @param width
695
     * @param height
696
     * @return
697
     */
698
    public double[] getScale(int width, int height) {
699
        double[] scale = new double[2];
700

    
701
        if (geoFile != null) {
702
            scale[0] = ((double) width) / geoFile[0].getView().width();
703
            scale[1] = ((double) height) / geoFile[0].getView().height();
704

    
705
            return scale;
706
        } else {
707
            System.err.println("PxRaster.getScale(): Imagen no cargada.");
708

    
709
            return null;
710
        }
711
    }
712

    
713
    /**
714
     * Transforma la petici?n que est? en coordenadas de la imagen sin rotar a coordenadas de la imagen rotada
715
     * para que sea posible el calculo de la caja m?nima de inclusi?n. La coordenada superior izquierda de esta
716
     * ser? la que se use para posicionar la imagen sobre el graphics aplicandole la transformaci?n de la la vista.
717
     * @param v
718
     * @return
719
     */
720
    private Point2D coordULRotateRaster(double[] v){
721
        double vx = v[0];
722
        double vy = v[1];
723
        double vx2 = v[2];
724
        double vy2 = v[3];
725
            if (geoFile != null) {
726
                double[] transf = geoFile[0].getTransform();
727
                                
728
                   if(transf != null && (transf[2] != 0 || transf[4] != 0)){
729
                           //La transformaci?n se hace en base a una esquina que varia con el signo del 
730
                           //pixel size. 
731
                           double ptoDesplX = (transf[1] > 0)?requestExtent.minX():requestExtent.maxX();
732
                    double ptoDesplY = (transf[5] < 0)?requestExtent.maxY():requestExtent.minY();
733
            
734
                    Point2D ul = new Point2D.Double(vx - ptoDesplX, vy2 - ptoDesplY);
735
                    Point2D ur = new Point2D.Double(vx2 - ptoDesplX, vy2 - ptoDesplY);
736
                    Point2D ll = new Point2D.Double(vx - ptoDesplX, vy - ptoDesplY);
737
                    Point2D lr = new Point2D.Double(vx2 - ptoDesplX, vy - ptoDesplY);
738
                    
739
                           double shearX = 0;
740
                double shearY = 0;
741
              
742
                if(transf[5] != 0)
743
                        shearX = transf[2] / transf[5];
744
                else
745
                        shearX = transf[2];
746
                if(transf[1] != 0)
747
                        shearY = transf[4] / transf[1];
748
                else
749
                        shearY = transf[4];
750
                
751
                
752
                        AffineTransform at = new AffineTransform();
753
                        at.setToShear(shearX, shearY);
754

    
755
                        at.transform(ul, ul);
756
                        at.transform(ur, ur);
757
                        at.transform(ll, ll);
758
                        at.transform(lr, lr);
759
                                
760
                        ul = new Point2D.Double(ul.getX() + ptoDesplX, ul.getY() + ptoDesplY);
761
                        ur = new Point2D.Double(ur.getX() + ptoDesplX, ur.getY() + ptoDesplY);
762
                        ll = new Point2D.Double(ll.getX() + ptoDesplX, ll.getY() + ptoDesplY);
763
                        lr = new Point2D.Double(lr.getX() + ptoDesplX, lr.getY() + ptoDesplY);
764
                        
765
                        vx2 = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
766
                        vy2 = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
767
                        vx = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
768
                        vy = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
769
                        adjustedRotedExtent = new double[4];
770
                        adjustedRotedExtent[0] = vx;
771
                        adjustedRotedExtent[1] = vy;
772
                        adjustedRotedExtent[2] = vx2;
773
                        adjustedRotedExtent[3] = vy2;
774
                        return ul;
775
                }
776
                   
777
        }
778
            return null;
779
        
780
    }
781
    
782
    /**
783
     * Ajusta la extensi?n pasada por par?metro y que corresponde al extent de la vista donde
784
     * se va a dibujar a los valores m?ximos y m?nimos de la imagen. Esto sirve para que la
785
     * petici?n al driver nunca sobrepase los l?mites de la imagen tratada aunque la vista
786
     * donde se dibuje sea de mayor tama?o.
787
     * 
788
     * Antes de realizar este ajuste hay que transformar la petici?n que puede corresponder a 
789
     * una imagen rotada a las coordenadas de la imagen sin rotar ya que las peticiones al 
790
     * driver hay que hacerlas con estas coordenadas. Para esto trasladamos la petici?n al origen
791
     * de la imagen (esquina superior izquierda), aplicamos la transformaci?n inversa a las cuatro 
792
     * esquinas obtenidas y volvemos a trasladar a su posici?n original. 
793
     * 
794
     * Se usa la transformaci?n inversa para trasladar un punto del raster rotado al mismo sin 
795
     * rotar y la transformaci?n af?n normal para trasladar un punto sin rotar a uno rotado.
796
     * 
797
     * @param sz Extent completo de la vista donde se va a dibujar.
798
     */
799
    protected double[] calculateNewView(ViewPortData vp) {
800
            Extent sz = vp.getExtent();
801
        double vx = sz.minX();
802
        double vy = sz.minY();
803
        double vx2 = sz.maxX();
804
        double vy2 = sz.maxY();
805
        
806
        //Trasladamos la petici?n si est? rotada a su posici?n sin rotar
807
        
808
        if (geoFile != null) {
809
                double[] transf = geoFile[0].getTransform();
810
                                
811
                   if(transf != null && (transf[2] != 0 || transf[4] != 0)){
812
                           
813
                           //La transformaci?n se hace en base a una esquina que varia con el signo del 
814
                           //pixel size. 
815
                           double ptoDesplX = (transf[1] > 0)?requestExtent.minX():requestExtent.maxX();
816
                    double ptoDesplY = (transf[5] < 0)?requestExtent.maxY():requestExtent.minY();
817
                    
818
                    Point2D ul = new Point2D.Double(vx - ptoDesplX, vy2 - ptoDesplY);
819
                    Point2D ur = new Point2D.Double(vx2 - ptoDesplX, vy2 - ptoDesplY);
820
                    Point2D ll = new Point2D.Double(vx - ptoDesplX, vy - ptoDesplY);
821
                    Point2D lr = new Point2D.Double(vx2 - ptoDesplX, vy - ptoDesplY);
822
                    
823
                           double shearX = 0;
824
                double shearY = 0;
825
                if(transf[5] != 0)
826
                        shearX = transf[2] / transf[5];
827
                else
828
                        shearX = transf[2];
829
                if(transf[1] != 0)
830
                        shearY = transf[4] / transf[1];
831
                else
832
                        shearY = transf[4];
833
                
834
                        AffineTransform at = new AffineTransform();
835
                        at.setToShear(shearX, shearY);
836
                        
837
                        try {
838
                                at.inverseTransform(ul, ul);
839
                                at.inverseTransform(ur, ur);
840
                                at.inverseTransform(ll, ll);
841
                                at.inverseTransform(lr, lr);
842
                                } catch (NoninvertibleTransformException e) {
843
                                        e.printStackTrace();
844
                                }
845
                                
846
                        ul = new Point2D.Double(ul.getX() + ptoDesplX, ul.getY() + ptoDesplY);
847
                        ur = new Point2D.Double(ur.getX() + ptoDesplX, ur.getY() + ptoDesplY);
848
                        ll = new Point2D.Double(ll.getX() + ptoDesplX, ll.getY() + ptoDesplY);
849
                        lr = new Point2D.Double(lr.getX() + ptoDesplX, lr.getY() + ptoDesplY);
850
                        
851
                        vx2 = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
852
                        vy2 = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
853
                        vx = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
854
                        vy = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
855
                }
856
        }
857

    
858
        if (vx < requestExtent.minX())
859
            vx = requestExtent.minX();
860
        
861
        if (vy < requestExtent.minY()) 
862
            vy = requestExtent.minY();
863
        
864
        if (vx2 > requestExtent.maxX()) 
865
            vx2 = requestExtent.maxX();
866
        
867
        if (vy2 > requestExtent.maxY())
868
            vy2 = requestExtent.maxY();
869
                
870
        if (geoFile != null) {
871
            for (int i = 0; i < geoFile.length; i++)
872
                    geoFile[i].setView(new Extent(vx, vy, vx2, vy2));
873
        } else {
874
            System.err.println("PxRaster.calculateNewView(): Imagen no cargada.");
875
        }
876
        double[] adjustedExtent = {vx, vy, vx2, vy2};
877
        return adjustedExtent;
878
    }
879
    
880
    /**
881
     * Aplica transparencia leyendo los metadatos
882
     */
883
    private void setTransparencyByPixel(){
884
            if(geoFile[0].getMetadata() != null){
885
                    if (stackManager == null){
886
                        TransparencyRange[] noData = geoFile[0].getMetadata().parserNodataInMetadata();
887
                        if(noData != null){
888
                        ArrayList entries = new ArrayList();
889
                        for(int i = 0; i < noData.length; i++)
890
                                  entries.add(noData[i]);
891
                        stackManager = new RasterFilterStackManager(filterStack);
892
                        stackManager.addTransparencyFilter(        entries, 0x0, 0xff, 0xff, 0xff);
893
                        }
894
                        TransparencyRange noDataValue = geoFile[0].getMetadata().parserNodataByBand();
895
                        if(noData == null  && noDataValue != null){
896
                        ArrayList entries = new ArrayList();
897
                        entries.add(noDataValue);
898
                        stackManager = new RasterFilterStackManager(filterStack);
899
                        stackManager.addTransparencyFilter(        entries, 0x0, 0xff, 0xff, 0xff);
900
                        }
901
                        
902
                    }
903
        }
904
    }
905
    public boolean service = false;
906
    
907
    /** Dibuja el raster sobre el Graphics. Para ello debemos de pasar el viewPort que corresponde a la
908
     * vista. Este viewPort es ajustado a los tama?os m?ximos y m?nimos de la imagen por la funci?n  
909
     * calculateNewView. Esta funci?n tambi?n asignar? la vista a los drivers. Posteriormente se calcula 
910
     * el alto y ancho de la imagen a dibujar (wImg, hImg), as? como el punto donde se va a pintar dentro 
911
     * del graphics (pt). Finalmente se llama a updateImage del driver para que pinte y una vez dibujado
912
     * se pasa a trav?s de la funci?n renderizeRaster que es la encargada de aplicar la pila de filtros
913
     * sobre el Image que ha devuelto el driver.
914
     * 
915
     * Para calcular en que coordenada pixel (pt) se empezar? a pintar el BufferedImage con el raster le?do
916
     * se aplica sobre la esquina superior izquierda de esta la matriz de transformaci?n del ViewPortData
917
     * pasado vp.mat.transform(pt, pt). Si el raster no est? rotado este punto es el resultante de la
918
     * funci?n calculateNewView que devuelve la petici?n ajustada al extent de la imagen (sin rotar). Si
919
     * el raster est? rotado necesitaremos para la transformaci?n el resultado de la funci?n coordULRotateRaster. 
920
     * Lo que hace esta ?ltima es colocar la petici?n que ha sido puesta en coordenadas de la imagen sin rotar
921
     * (para pedir al driver de forma correcta) otra vez en coordenadas de la imagen rotada (para calcular su 
922
     * posici?n de dibujado).
923
     * 
924
     * Para dibujar sobre el Graphics2D el raster rotado aplicaremos la matriz de transformaci?n con los 
925
     * par?metros de Shear sobre este Graphics de forma inversa. Como hemos movido el fondo tendremos que
926
     * recalcular ahora el punto donde se comienza a dibujar aplicandole la transformaci?n sobre este
927
     * at.inverseTransform(pt, pt);. Finalmente volcamos el BufferedImage sobre el Graphics volviendo a dejar
928
     * el Graphics en su posici?n original al acabar. 
929
     * 
930
     * @param g Graphics sobre el que se pinta
931
     * @param vp ViewPort de la extensi?n a dibujar
932
     */
933
    public synchronized void draw(Graphics2D g, ViewPortData vp) {
934
        geoImage = null;
935
            double shearX = 0;
936
        double shearY = 0;
937
        
938
        long t2;
939
        long t1 = new Date().getTime();
940
        lastViewPort = vp;
941
            
942
        if ((vp.getExtent().minX() > extent.maxX()) ||
943
                (vp.getExtent().minY() > extent.maxY()) ||
944
                (vp.getExtent().maxX() < extent.minX()) ||
945
                (vp.getExtent().maxY() < extent.minY())) {
946
            return;
947
        }
948

    
949
        double[] adjustedExtent = calculateNewView(vp);
950
        Point2D p2d = coordULRotateRaster(adjustedExtent);
951

    
952
        Extent v = geoFile[0].getView();
953
        double x = v.minX();
954
        double y = v.minY();
955
        double w = v.width();
956
        double h = v.height();
957

    
958
        double scalex = vp.mat.getScaleX();
959
        double scaley = vp.mat.getScaleY();
960
        
961
        /*int wImg = (int) Math.round(Math.abs(w * scalex));
962
        int hImg = (int) Math.round(Math.abs(h * scaley));*/
963
        int wImg = (int) Math.round(Math.abs((adjustedExtent[2] - adjustedExtent[0]) * scalex));
964
        int hImg = (int) Math.round(Math.abs((adjustedExtent[3] - adjustedExtent[1]) * scaley));
965

    
966
        if ((wImg <= 0) || (hImg <= 0))
967
            return;
968
        
969
        //Para la transformaci?n usamos el extent que ha ajustado la funci?n calculateNewView y no usamos 
970
        //el getView porque el getView puede haber  sufrido una transformaci?n en caso de que exista 
971
        //fichero .rmf. En caso de no existir este fichero ser?a lo mismo aplicar la funci?n:
972
        //Point2D.Double pt = new Point2D.Double(x, y + h);
973
        int wI = wImg, hI = hImg;
974
        double[] transf = bandSwitch.getBandR().getGeoRasterFile().getTransform();
975
        Point2D.Double pt = null;
976
               if(transf != null && (transf[2] != 0 || transf[4] != 0)){ //Esta rotada
977
                       pt =  new Point2D.Double(p2d.getX(), p2d.getY());
978
                       wImg = (int) Math.round(Math.abs((adjustedRotedExtent[2] - adjustedRotedExtent[0]) * scalex));
979
            hImg = (int) Math.round(Math.abs((adjustedRotedExtent[3] - adjustedRotedExtent[1]) * scaley));
980
               }else{        //No est? rotada
981
                               pt = new Point2D.Double(adjustedExtent[0], adjustedExtent[3]);
982
               }
983
        
984
        try {
985
            vp.mat.transform(pt, pt);
986
            
987
            setTransparencyByPixel();
988
                        
989
            if ((geoFile != null) && (geoFile[0] instanceof GdalFile || geoFile[0] instanceof MemoryRasterDriver) &&
990
                    (geoFile[0].getDataType() != DataBuffer.TYPE_BYTE)) {
991
                    RasterBuf raster = null;
992
                    if (geoFile.length > 1) { // la imagen sale de distintos ficheros
993
                            RasterBuf rasterG=null, rasterB=null;
994
                        raster = ((GdalFile) bandSwitch.getBandR().getGeoRasterFile()).getRaster(wImg, hImg, rp);
995
                        rasterG = ((GdalFile) bandSwitch.getBandG().getGeoRasterFile()).getRaster(wImg, hImg, rp);
996
                        raster.copyBand(rasterG, 0, 1);
997
                        rasterB = ((GdalFile) bandSwitch.getBandB().getGeoRasterFile()).getRaster(wImg, hImg, rp);
998
                        raster.copyBand(rasterB, 0, 2);
999
                    } else { // Toda la imagen est? en el mismo fichero
1000
                            if(geoFile[0] instanceof MemoryRasterDriver)
1001
                                    raster = ((MemoryRasterDriver) geoFile[0]).getRaster(wImg, hImg, rp);
1002
                            else
1003
                                    raster = ((GdalFile) geoFile[0]).getRaster(wImg, hImg, rp);
1004
                    } 
1005
                    t2 = new Date().getTime();
1006

    
1007
                System.out.println("Dibujando PxRaster: " + ((t2 - t1) / 1000D) + ", secs. Filtrando/Renderizando");
1008
                t1 = t2;
1009

    
1010
                filterStack.setInitRasterBuf(raster);
1011

    
1012
                //Si la imagen es de 16 bits lleva un filtro de realce por defecto
1013
                if (stackManager == null){
1014
                    stackManager = new RasterFilterStackManager(filterStack);
1015
                    stackManager.addEnhancedFilter(false, geoFile[0].getName());
1016
                    stackManager.removeFilter(stackManager.getTypeFilter("computeminmax"));
1017
                    stackManager.addTailFilter(this.percentFilterInit, 0D, true);
1018
                }
1019
                
1020
                //Para imagenes de una banda replicamos esta en el resto del rasterBuf
1021
                if(raster.getBandCount() == 1){
1022
                        raster.replicateBand(0, 1);
1023
                        raster.replicateBand(0, 2);
1024
                }
1025
                
1026
                geoImage = renderizeRaster(raster, vp, v);
1027
                g.drawImage(geoImage, (int)(pt.getX()), (int)(pt.getY()), component);
1028
            } else if((geoFile != null) && (geoFile.length > 1) && 
1029
                            (!bandSwitch.getBandR().getGeoRasterFile().getName().equals(bandSwitch.getBandG().getGeoRasterFile().getName()) || 
1030
                            !bandSwitch.getBandR().getGeoRasterFile().getName().equals(bandSwitch.getBandB().getGeoRasterFile().getName()) ||
1031
                            !bandSwitch.getBandG().getGeoRasterFile().getName().equals(bandSwitch.getBandB().getGeoRasterFile().getName()))
1032
                            ) { // multiFiles
1033
                System.out.println("Dibujando PxRaster (Multifile) ... Bands " +
1034
                                   geoFile.length);
1035

    
1036
                if (bandSwitch.getBandR().getGeoRasterFile() instanceof EcwFile) {
1037
                    ((EcwFile) bandSwitch.getBandR().getGeoRasterFile()).setMultifile(true);
1038
                }
1039

    
1040
                if (bandSwitch.getBandG().getGeoRasterFile() instanceof EcwFile) {
1041
                    ((EcwFile) bandSwitch.getBandG().getGeoRasterFile()).setMultifile(true);
1042
                }
1043

    
1044
                if (bandSwitch.getBandB().getGeoRasterFile() instanceof EcwFile) {
1045
                    ((EcwFile) bandSwitch.getBandB().getGeoRasterFile()).setMultifile(true);
1046
                }
1047
                
1048
                //TODO:Soluci?n para que no se pinte si hay sharpening. Esto hay que pensarlo mejor
1049
                if (stackManager == null) 
1050
                    stackManager = new RasterFilterStackManager(filterStack);
1051
                if (!filterStack.isActive(stackManager.getTypeFilter("sharpening"))){
1052
                        geoImage = bandSwitch.getBandR().getGeoRasterFile().updateImage(wImg, hImg, rp, null, 0, 0);
1053
                        geoImage = bandSwitch.getBandG().getGeoRasterFile().updateImage(wImg, hImg, rp, geoImage, 
1054
                                                                        bandSwitch.getBandG().getBand(), GeoRasterFile.GREEN_BAND);
1055
                        geoImage = bandSwitch.getBandB().getGeoRasterFile().updateImage(wImg, hImg, rp, geoImage, 
1056
                                                                        bandSwitch.getBandB().getBand(), GeoRasterFile.BLUE_BAND);
1057
                }else{
1058
                        geoImage = new BufferedImage(wImg, hImg, BufferedImage.TYPE_INT_RGB);
1059
                }
1060
                
1061
                filterStack.setInitRasterBuf(geoImage);
1062
                
1063
                geoImage = renderizeRaster(geoImage, vp, v);
1064

    
1065
                g.drawImage(geoImage, (int)(pt.getX()), (int)(pt.getY()), component);
1066
            } else if ((geoFile != null) ) { // Una solo fichero
1067

    
1068
                    geoImage = bandSwitch.getBandR().getGeoRasterFile().updateImage(wImg, hImg, rp, null, 0, 0);
1069
                    
1070
                    if (stackManager == null)
1071
                    stackManager = new RasterFilterStackManager(filterStack);
1072
                PaletteStackManager psm = (PaletteStackManager)stackManager.getManagerByClass(PaletteStackManager.class);
1073
                
1074
                    /*
1075
                     * WARNING: Si cada vez que vamos a visualizar le aplicamos la paleta asociada el GeoRasterFile
1076
                     * las modificaciones que hacemos desde el interfaz no puede tenerse en cuenta pq se machaca a cada visualizaci?n.
1077
                     * Si usamos la paleta que hemos modificado entonces a cada zoom de WMS la visualizaci?n sale erronea ya que
1078
                     * a cada nivel de escala la paleta cambia aplicando entonces una paleta erronea ya que estar?amos aplicando 
1079
                     * la primera paleta con que se visualiz?.
1080
                     */
1081
                    if(bandSwitch.getBandR().getGeoRasterFile().getPalette() != null){
1082
                            PaletteFilter pf = (PaletteFilter)filterStack.getByType(PaletteStackManager.palette);
1083
                            if(pf == null){
1084
                        //TODO:
1085
                        //* A la funci?n addPaletteFilter se le pasa el valor false al par?metro interpolate, lo cual no ser? v?lido
1086
                        //* si se leen rasters con paletas asociadas que puedan especificar si se interpola o no, por ejemplo un rmf 
1087
                        //* cuando se dote a estos de la posibilidad de almacenar paletas. Para este cas? hay que buscar la forma de saber
1088
                        //* en este punto si la paleta asociada al GeoRasterFile se visualiza con o sin interpolaci?n.  
1089
                        //*             
1090
                        psm.addPaletteFilter(bandSwitch.getBandR().getGeoRasterFile().getPalette(),false);
1091
                        
1092
                            }else{
1093
                                    //TODO: A modificar. Se debe a?adir la paleta en el servicio q la necesita aplicar y no
1094
                                    //aqu?. No se ha podido hacer esto de otra forma pq no hay manera de saber si la llamada 
1095
                                    //la hace un servicio o un servicio remoto sin pasar par?metros. Como tiene q ir sobre la 1.0.1
1096
                                    //No puedo modificar los servicios para que comunique esto. Esto caduca con el refactoring.
1097
                                    int index = bandSwitch.getBandR().getGeoRasterFile().getName().lastIndexOf(File.separator);
1098
                                    String fname = bandSwitch.getBandR().getGeoRasterFile().getName().substring(index + 1);
1099
                                    if(fname.startsWith("wmsGetMap") || fname.startsWith("wcsGetMap")){
1100
                                            bandSwitch.getBandR().getGeoRasterFile().readPalette();
1101
                                            psm.addPaletteFilter(bandSwitch.getBandR().getGeoRasterFile().getPalette(),false);
1102
                                    }
1103
                            }
1104
                    }
1105
                                                
1106
                    
1107
                filterStack.setInitRasterBuf(geoImage);
1108

    
1109
                geoImage = renderizeRaster(geoImage, vp, v);
1110
                
1111
                AffineTransform at = new AffineTransform();
1112

    
1113
                if(transf != null && (transf[2] != 0 || transf[4] != 0)){
1114
                                                
1115
                        //Obtenemos los par?metros de shearing
1116
                        if(transf[5] != 0)
1117
                                shearX = transf[2] / transf[5];
1118
                        else
1119
                                shearX = transf[2];
1120
                        if(transf[1] != 0)
1121
                                shearY = transf[4] / transf[1];
1122
                        else
1123
                                shearY = transf[4];
1124
                        
1125
                        //Aplicamos el shear a la vista
1126
                                at.setToShear(-shearX, -shearY);
1127
                                
1128
                                //Escalamos en pixeles la misma cantidad que hemos le?do de m?s.  
1129
                                at.scale(((double)wI/(double)wImg), ((double)hI/(double)hImg));
1130
                                                                                                                      
1131
                                g.transform(at);
1132
                                
1133
                                //Aplicamos el shear inverso al punto donde se comienza a dibujar
1134
                                at.inverseTransform(pt, pt);
1135
                                
1136
                                g.drawImage(geoImage, (int) (pt.getX()), (int) (pt.getY()), component);
1137
                                g.transform(at.createInverse());
1138
                }else
1139
                        g.drawImage(geoImage, (int) (pt.getX()), (int) (pt.getY()), component);
1140
               
1141
            } else { // no cargada
1142
                System.err.println("Dibujando PxRaster: Foto no cargada.");
1143
            }
1144
            
1145
            t2 = new Date().getTime();
1146
            System.out.println("Dibujando PxRaster: " + ((t2 - t1) / 1000D) + ", secs.");
1147
        }catch (SupersamplingNotSupportedException e) {
1148
            System.err.println("Supersampling not supported");
1149
            return;
1150
        }catch (Exception e) {
1151
            e.printStackTrace();
1152
        }
1153
        
1154
        if (pintaMarco) {
1155
            drawMarco(g, vp);
1156
        }
1157
    }
1158

    
1159
    /**
1160
     * Aplica la pila de fitros sobre el RasterBuf pasado como par?metro
1161
     * y lo devuelve en Image
1162
     * @param raster        RasterBuf con la imagen sobre la que se aplicaran filtros
1163
     * @return        Image con la imagen con los filtros puestos
1164
     */
1165
    public Image renderizeRaster(RasterBuf raster, ViewPortData vp, Extent e) {
1166
        if (filterStack != null) {
1167
                filterStack.setViewPortData(vp);
1168
                filterStack.setExtent(e);
1169
                filterStack.setStep(geoFile[0].getStepX(), geoFile[0].getStepY());
1170
            raster = filterStack.execute(raster);
1171
        }
1172
        System.out.println("Image renderizeRaster(RasterBuf raster, ViewPortData vp) ");
1173
        //Aplicamos el filtro para convertir a Image
1174
        
1175
        RasterToImageFilter rti = null;
1176
        if(getDataType() == RasterBuf.TYPE_BYTE){
1177
                rti = new RasterByteToImageFilter();        
1178
        }else if(getDataType() == RasterBuf.TYPE_SHORT){
1179
                rti = new RasterShortToImageFilter();
1180
        }else if(getDataType() == RasterBuf.TYPE_INT){
1181
                rti = new RasterIntToImageFilter();
1182
        }else if(getDataType() == RasterBuf.TYPE_FLOAT){
1183
                rti = new RasterFloatToImageFilter();
1184
        }else if(getDataType() == RasterBuf.TYPE_DOUBLE){
1185
                rti = new RasterDoubleToImageFilter();
1186
        }
1187
        
1188
        
1189
        //rti.addParam("raster", raster);
1190
        if (filterStack.getOutDataType()!= RasterBuf.TYPE_IMAGE){
1191
                rti.addParam("raster", filterStack.getResult());
1192
                rti.addParam("alpha", new Integer(this.getAlpha()));
1193
                rti.execute();
1194
                raster = null;
1195
                return (Image) rti.getResult("raster");
1196
        }
1197
        else
1198
                return (Image)filterStack.getResult();
1199
    }
1200

    
1201
    /**
1202
     * Aplica la pila de filtros sobre el Image pasado como par?metro y lo devuelve.
1203
     * Si la salida del ?ltimo filtro es un RasterBuf lo convertir? a Image
1204
     * @param image Image con la imagen sobre la que se aplicaran filtros
1205
     * @return        Image con la imagen con los filtros puestos
1206
     */
1207
    public Image renderizeRaster(Image image, ViewPortData vp, Extent e) {
1208
        if (filterStack != null) {
1209
                filterStack.setViewPortData(vp);
1210
                filterStack.setExtent(e);
1211
                filterStack.setStep(geoFile[0].getStepX(), geoFile[0].getStepY());
1212
            filterStack.execute(image);
1213
        }
1214
      
1215
        if (filterStack.getOutDataType() != RasterBuf.TYPE_IMAGE) {
1216
            //Aplicamos el filtro para convertir a Image
1217
                
1218
                     RasterToImageFilter rti = null;
1219
                 if(getDataType() == RasterBuf.TYPE_BYTE){
1220
                         rti = new RasterByteToImageFilter();        
1221
                 }else if(getDataType() == RasterBuf.TYPE_SHORT){
1222
                         rti = new RasterShortToImageFilter();
1223
                 }else if(getDataType() == RasterBuf.TYPE_INT){
1224
                         rti = new RasterIntToImageFilter();
1225
                 }else if(getDataType() == RasterBuf.TYPE_FLOAT){
1226
                         rti = new RasterFloatToImageFilter();
1227
                 }else if(getDataType() == RasterBuf.TYPE_DOUBLE){
1228
                         rti = new RasterDoubleToImageFilter();
1229
                 }
1230
          
1231
            //RasterIntToImageFilter rti = new RasterIntToImageFilter();
1232
            
1233
                 rti.addParam("raster", (RasterBuf) filterStack.getResult());
1234
                 rti.addParam("alpha", new Integer(this.getAlpha()));
1235
                 rti.execute();
1236
         
1237
                 return (Image) rti.getResult("raster");
1238
        }        
1239
        return (Image) filterStack.getResult();
1240
       // return image;
1241
    }
1242

    
1243
    /**
1244
     *
1245
     * @param g
1246
     * @param vp
1247
     */
1248
    public void drawMarco(Graphics2D g, ViewPortData vp) {
1249
        //                Color color = new Color(255,222,165,128), fillColor = new Color(255,214,132,128);
1250
        Color color = new Color(128, 128, 128);
1251

    
1252
        //                Color color = new Color(255,222,165,128), fillColor = new Color(255,214,132,128);
1253
        Color fillColor = new Color(255, 220, 220, 0x20);
1254
        GeneralPath gp = newGP(vp);
1255
        g.setColor(fillColor);
1256
        g.fill(gp);
1257
        g.setColor(color);
1258
        g.draw(gp);
1259
    }
1260

    
1261
    private GeneralPath newGP(ViewPortData vp) {
1262
        //if (gp != null) return;
1263
        GeneralPath gp = new GeneralPath();
1264
        Point2D.Double pt0 = new Point2D.Double(0.0, 0.0);
1265
        Point2D.Double pt1 = new Point2D.Double(0.0, 0.0);
1266
        Point2D.Double pt2 = new Point2D.Double(0.0, 0.0);
1267
        Point2D.Double pt3 = new Point2D.Double(0.0, 0.0);
1268
        vp.mat.transform((Point2D) pts.get(0), pt0);
1269
        vp.mat.transform((Point2D) pts.get(1), pt1);
1270
        vp.mat.transform((Point2D) pts.get(2), pt2);
1271
        vp.mat.transform((Point2D) pts.get(3), pt3);
1272

    
1273
        // Aspa desde el extent
1274
        gp.moveTo((float) pt0.getX(), (float) pt0.getY());
1275
        gp.lineTo((float) pt2.getX(), (float) pt2.getY());
1276
        gp.moveTo((float) pt1.getX(), (float) pt1.getY());
1277
        gp.lineTo((float) pt3.getX(), (float) pt3.getY());
1278

    
1279
        // Extent
1280
        gp.moveTo((float) pt0.getX(), (float) pt0.getY());
1281
        gp.lineTo((float) pt1.getX(), (float) pt1.getY());
1282
        gp.lineTo((float) pt2.getX(), (float) pt2.getY());
1283
        gp.lineTo((float) pt3.getX(), (float) pt3.getY());
1284

    
1285
        if (extentOrig != extent) {
1286
            gp.lineTo((float) pt0.getX(), (float) pt0.getY());
1287

    
1288
            Vector pts = new Vector();
1289
            pts.add(proj.createPoint(extentOrig.minX(), extentOrig.minY()));
1290
            pts.add(proj.createPoint(extentOrig.maxX(), extentOrig.minY()));
1291
            pts.add(proj.createPoint(extentOrig.maxX(), extentOrig.maxY()));
1292
            pts.add(proj.createPoint(extentOrig.minX(), extentOrig.maxY()));
1293

    
1294
            vp.mat.transform((Point2D) pts.get(0), pt0);
1295
            vp.mat.transform((Point2D) pts.get(1), pt1);
1296
            vp.mat.transform((Point2D) pts.get(2), pt2);
1297
            vp.mat.transform((Point2D) pts.get(3), pt3);
1298
            gp.moveTo((float) pt0.getX(), (float) pt0.getY());
1299
            gp.lineTo((float) pt1.getX(), (float) pt1.getY());
1300
            gp.lineTo((float) pt2.getX(), (float) pt2.getY());
1301
            gp.lineTo((float) pt3.getX(), (float) pt3.getY());
1302
        }
1303

    
1304
        gp.closePath();
1305

    
1306
        return gp;
1307
    }
1308

    
1309
    public IProjection getProjection() {
1310
        return proj;
1311
    }
1312

    
1313
    public void setProjection(IProjection p) {
1314
        proj = p;
1315
    }
1316

    
1317
    public void reProject(ICoordTrans rp) {
1318
        this.rp = rp.getInverted();
1319
        System.out.println("PxRaster: reProject()");
1320

    
1321
        //geoFile.reProject(rp);
1322
        Vector savePts = pts;
1323

    
1324
        pts = new Vector();
1325
        extent = new Extent();
1326

    
1327
        Point2D ptDest = null;
1328

    
1329
        for (int i = 0; i < savePts.size(); i++) {
1330
            ptDest = rp.getPDest().createPoint(0.0, 0.0);
1331
            ptDest = rp.convert((Point2D) savePts.get(i), ptDest);
1332
            pts.add(ptDest);
1333
            extent.add(ptDest);
1334
        }
1335

    
1336
        setProjection(rp.getPDest());
1337
    }
1338

    
1339
    /**
1340
     * Obtiene el Stack Manager
1341
     * @return
1342
     */
1343
    public RasterFilterStackManager getStackManager() {
1344
        return this.stackManager;
1345
    }
1346

    
1347
    /**
1348
     * Asigna el Stack Manager
1349
     * @return
1350
     */
1351
    public void setStackManager(RasterFilterStackManager sm) {
1352
        this.stackManager = sm;
1353
    }
1354

    
1355
    /**
1356
     * Estructura que representa la relaci?n entre un fichero y la banda que se
1357
     * utiliza de este.
1358
     * @author Nacho Brodin <brodin_ign@gva.es>
1359
     */
1360
    class FileBands {
1361
        GeoRasterFile grf; //Fichero
1362
        int band; //Banda asinada
1363
        int filePos; //posici?n del fichero
1364

    
1365
        /**
1366
         * @return Returns the band.
1367
         */
1368
        public int getBand() {
1369
            return band;
1370
        }
1371

    
1372
        /**
1373
         * @param band The band to set.
1374
         */
1375
        public void setBand(int band) {
1376
            this.band = band;
1377
        }
1378

    
1379
        /**
1380
         * @return Returns the band.
1381
         */
1382
        public int getPos() {
1383
            return filePos;
1384
        }
1385

    
1386
        /**
1387
         * @param band The band to set.
1388
         */
1389
        public void setPos(int pos) {
1390
            this.filePos = pos;
1391
        }
1392

    
1393
        /**
1394
         * @return Returns the grf.
1395
         */
1396
        public GeoRasterFile getGeoRasterFile() {
1397
            return grf;
1398
        }
1399

    
1400
        /**
1401
         * @param grf The grf to set.
1402
         */
1403
        public void setGeoRasterFile(GeoRasterFile grf) {
1404
            this.grf = grf;
1405
        }
1406
    }
1407

    
1408
    /**
1409
     * Clase que lleva la gesti?n entre la relaci?n de ficheros representados
1410
     * por un GeoRasterFile y el n?mero de bandas que contienen. Esto es necesario
1411
     * para la actualizaci?n de la vista ya que para un Image dado podemos tener
1412
     * multiples bandas que pueden ser leidas desde diferentes ficheros.
1413
     *
1414
     * @author Nacho Brodin <brodin_ign@gva.es>
1415
     */
1416
    class BandSwitch {
1417
        private ArrayList geoFiles = new ArrayList(); //Lista de GeoRasterFile con los ficheros raster cargados
1418
        private FileBands[] listBands = new FileBands[3];
1419
        private boolean debug = false;
1420

    
1421
        BandSwitch() {
1422
            for (int i = 0; i < listBands.length; i++)
1423
                listBands[i] = new FileBands();
1424
        }
1425

    
1426
        /**
1427
         * A?ade un fichero
1428
         * @param grf
1429
         */
1430
        public void addFile(GeoRasterFile grf) {
1431
            geoFiles.add(grf);
1432

    
1433
            if (debug) {
1434
                this.show("addFile");
1435
            }
1436
        }
1437

    
1438
        /**
1439
         * Elimina un fichero
1440
         * @param grf
1441
         */
1442
        public void removeFile(GeoRasterFile grf) {
1443
            for (int iFile = 0; iFile < geoFiles.size(); iFile++) {
1444
                if (grf.equals(geoFiles.get(iFile))) {
1445
                    geoFiles.remove(iFile);
1446
                    iFile--;
1447
                }
1448
            }
1449

    
1450
            if (debug) {
1451
                this.show("removeFile");
1452
            }
1453
        }
1454

    
1455
        /**
1456
         *
1457
         * @param flag
1458
         * @param grf
1459
         * @param nBand
1460
         */
1461
        public void setBand(int flag, GeoRasterFile grf, int nBand) {
1462
            if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) {
1463
                listBands[0].setBand(nBand);
1464
                listBands[0].setGeoRasterFile(grf);
1465
            } else if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) {
1466
                listBands[1].setBand(nBand);
1467
                listBands[1].setGeoRasterFile(grf);
1468
            } else if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) {
1469
                listBands[2].setBand(nBand);
1470
                listBands[2].setGeoRasterFile(grf);
1471
            } else {
1472
                return;
1473
            }
1474

    
1475
            grf.setBand(flag, nBand);
1476
        }
1477

    
1478
        /**
1479
         * Asigna las bandas
1480
         * @param flag
1481
         * @param nBand
1482
         */
1483
        public void setBand(int flag, int nBand) {
1484
            int cont = 0;
1485

    
1486
            for (int iGrf = 0; iGrf < geoFiles.size(); iGrf++) {
1487
                for (int iBand = 0;
1488
                         iBand < ((GeoRasterFile) geoFiles.get(iGrf)).getBandCount();
1489
                         iBand++) {
1490
                    if (((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) &&
1491
                            (cont == nBand)) {
1492
                        listBands[0].setGeoRasterFile(((GeoRasterFile) geoFiles.get(iGrf)));
1493
                        listBands[0].setBand(iBand);
1494
                        listBands[0].setPos(iGrf);
1495
                        ((GeoRasterFile) geoFiles.get(iGrf)).setBand(flag, iBand);
1496

    
1497
                        //System.out.println("==>Asignando banda R FILE="+iGrf+" BANDA="+iBand);
1498
                    } else if (((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) &&
1499
                                   (cont == nBand)) {
1500
                        listBands[1].setGeoRasterFile(((GeoRasterFile) geoFiles.get(iGrf)));
1501
                        listBands[1].setBand(iBand);
1502
                        listBands[1].setPos(iGrf);
1503
                        ((GeoRasterFile) geoFiles.get(iGrf)).setBand(flag, iBand);
1504

    
1505
                        //System.out.println("==>Asignando banda G FILE="+iGrf+" BANDA="+iBand);
1506
                    } else if (((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) &&
1507
                                   (cont == nBand)) {
1508
                        listBands[2].setGeoRasterFile(((GeoRasterFile) geoFiles.get(iGrf)));
1509
                        listBands[2].setBand(iBand);
1510
                        listBands[2].setPos(iGrf);
1511
                        ((GeoRasterFile) geoFiles.get(iGrf)).setBand(flag, iBand);
1512

    
1513
                        //System.out.println("==>Asignando banda B FILE="+iGrf+" BANDA="+iBand);
1514
                    }
1515

    
1516
                    cont++;
1517
                }
1518
            }
1519

    
1520
            if (debug) {
1521
                this.show("setBand");
1522
            }
1523
        }
1524

    
1525
        /**
1526
         * Obtiene el n?mero de bandas
1527
         * @return
1528
         */
1529
        public int getBandCount() {
1530
            int nbandas = 0;
1531

    
1532
            for (int iGrf = 0; iGrf < geoFiles.size(); iGrf++)
1533
                nbandas += ((GeoRasterFile) geoFiles.get(iGrf)).getBandCount();
1534

    
1535
            return nbandas;
1536
        }
1537

    
1538
        /**
1539
         * Obtiene el GeoRasterFile que hay que leer para cargar la banda del rojo
1540
         * y la banda de este fichero que se utiliza para esta asignaci?n.
1541
         * @return        Estructura FileBand con la relaci?n fichero-banda
1542
         */
1543
        public FileBands getBandR() {
1544
            return listBands[0];
1545
        }
1546

    
1547
        /**
1548
         * Obtiene el GeoRasterFile que hay que leer para cargar la banda del verde
1549
         * y la banda de este fichero que se utiliza para esta asignaci?n.
1550
         * @return        Estructura FileBand con la relaci?n fichero-banda
1551
         */
1552
        public FileBands getBandG() {
1553
            return listBands[1];
1554
        }
1555

    
1556
        /**
1557
         * Obtiene el GeoRasterFile que hay que leer para cargar la banda del azul
1558
         * y la banda de este fichero que se utiliza para esta asignaci?n.
1559
         * @return        Estructura FileBand con la relaci?n fichero-banda
1560
         */
1561
        public FileBands getBandB() {
1562
            return listBands[2];
1563
        }
1564

    
1565
        public void show(String op) {
1566
            String banda = null;
1567
            System.out.println("** " + op + " **");
1568

    
1569
            for (int i = 0; i < 3; i++) {
1570
                if (i == 0) {
1571
                    banda = new String("Rojo");
1572
                } else if (i == 1) {
1573
                    banda = new String("Verde");
1574
                } else if (i == 2) {
1575
                    banda = new String("Azul");
1576
                }
1577

    
1578
                System.out.println("** BANDA IMAGE=" + banda + " FILEPOS=" +
1579
                                   listBands[i].getBand() +
1580
                                   " BANDA DEL FICHERO=" +
1581
                                   listBands[i].getBand());
1582
            }
1583
        }
1584
    }
1585
        /**
1586
         * @return Returns the vName.
1587
         */
1588
        public String getVName() {
1589
                return vName;
1590
        }
1591
        /**
1592
         * @param name The vName to set.
1593
         */
1594
        public void setVName(String name) {
1595
                vName = name;
1596
        }
1597

    
1598
        /**
1599
         * Obtiene el ?ltimo Image volcado en pantalla 
1600
         * @return
1601
         */
1602
        public Image getGeoImage() {
1603
                return geoImage;
1604
        }
1605

    
1606
        /**
1607
         * Obtiene el ?ltimo viewPort de la vista
1608
         * @return ViewPortData
1609
         */
1610
        public ViewPortData getLastViewPort() {
1611
                return lastViewPort;
1612
        }
1613
}