Statistics
| Revision:

svn-gvsig-desktop / tags / gvSIGv0_6_1RELEASE / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrRaster.java @ 5222

History | View | Annotate | Download (17.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 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
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.awt.Dimension;
44
import java.awt.Graphics2D;
45
import java.awt.Point;
46
import java.awt.Rectangle;
47
import java.awt.geom.AffineTransform;
48
import java.awt.geom.NoninvertibleTransformException;
49
import java.awt.geom.Rectangle2D;
50
import java.awt.image.BufferedImage;
51
import java.io.File;
52
import java.lang.reflect.Constructor;
53
import java.lang.reflect.InvocationTargetException;
54
import java.util.ArrayList;
55

    
56
import org.cresques.cts.IProjection;
57
import org.cresques.io.raster.RasterBuf;
58
import org.cresques.io.raster.RasterFilterStack;
59
import org.cresques.io.raster.RasterStats;
60
import org.cresques.io.raster.RasterStats.History;
61
import org.cresques.px.Extent;
62

    
63
import com.hardcode.driverManager.Driver;
64
import com.hardcode.driverManager.DriverLoadException;
65
import com.iver.cit.gvsig.fmap.DriverException;
66
import com.iver.cit.gvsig.fmap.ViewPort;
67
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
68
import com.iver.cit.gvsig.fmap.drivers.GeorreferencedRasterDriver;
69
import com.iver.cit.gvsig.fmap.operations.Cancellable;
70
import com.iver.utiles.XMLEntity;
71

    
72

    
73
/**
74
 * Clase b?sica de capa raster.
75
 *
76
 * @author Vicente Caballero Navarro
77
 */
78
public class FLyrRaster extends FLyrDefault implements RasterOperations {
79
        private RasterAdapter                                 source;
80
        boolean                                                         isPrinting = false;
81
        boolean                                                         mustTileDraw = false;
82
        boolean                                                         mustTilePrint = true;
83
        int                                                                 maxTileDrawWidth = -1;
84
        int                                                                 maxTileDrawHeight = -1;
85
        int                                                                 maxTilePrintWidth = 1500;
86
        int                                                                 maxTilePrintHeight = 1500;
87
        private StatusRasterInterface                status = null;
88
        private boolean                                                firstLoad = false;
89
        private int                                                 posX = 0, posY = 0;
90
        private double                                                 posXWC = 0, posYWC = 0;
91
        private int                                                 r = 0, g = 0, b = 0;
92
        private boolean                                                removeRasterFlag = true;
93
                
94
        /**
95
         * Devuelve el RasterAdapter de la capa.
96
         *
97
         * @return RasterAdapter.
98
         */
99
        public RasterAdapter getSource() {
100
                return source;
101
        }
102

    
103
        /**
104
         *Redefine wakeUp de FLyrDefault
105
         */
106
        public void wakeUp(){
107
                setName(getName());
108
                setProjection(getProjection());
109
                try {
110
                        load();
111
                } catch (DriverIOException e) {
112
                        e.printStackTrace();
113
                }
114
        }
115
        
116
        /**
117
         * Inserta el RasterAdapter.
118
         *
119
         * @param ra RasterAdapter.
120
         */
121
        public void setSource(RasterAdapter ra) {
122
                source = ra;
123
        }
124

    
125
        /**
126
         * Devuelve la pila de filtros aplicada sobre  la capa raster.
127
         *
128
         * @return RasterFilterStack.
129
         */
130
        public RasterFilterStack getFilterStack(){
131
                return source.getFilterStack();
132
        }
133
        
134
        /**
135
         * Asignar el estado del raster
136
         * @param status
137
         */
138
        public void setStatus(StatusRasterInterface status){
139
                this.status = status;
140
        }
141
        
142
        /**
143
         * Asigna la pila de filtros aplicada al raster
144
         * @return
145
         */
146
        public void setFilterStack(RasterFilterStack stack){
147
                source.setFilterStack(stack);                
148
        }
149
        
150
        /**
151
         * Obtiene el estado del raster
152
         * @return
153
         */
154
        public StatusRasterInterface getStatus(){
155
                return this.status;
156
        }
157
        
158
        /**
159
         * Asigna la posici?n en la que se ha hecho click al mostrar
160
         * informaci?n del raster.
161
         * @param x        Posici?n en X
162
         * @param y        Posici?n en Y
163
         */
164
        public void setPos(int x, int y){
165
                this.posX = x;
166
                this.posY = y;
167
        }
168
        
169
        /**
170
         * Asigna la posici?n en coordenadas del mundo real en la que se ha 
171
         * hecho click al mostrar informaci?n del raster.
172
         * @param x        Posici?n en X
173
         * @param y        Posici?n en Y
174
         */
175
        public void setPosWC(double x, double y){
176
                this.posXWC = x;
177
                this.posYWC = y;
178
        }
179
        
180
        /**
181
         * Asigna RGB en la posici?n en la que se ha 
182
         * hecho click al mostrar informaci?n del raster.
183
         * @param r        valor de rojo
184
         * @param g        valor de verde
185
         * @param b        valor de azul
186
         */
187
        public void setRGB(int r, int g, int b){
188
                this.r = r;
189
                this.g = g;
190
                this.b = b;
191
        }
192
        
193
        /*
194
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#load()
195
         */
196
        public void load() throws DriverIOException {
197
                ((RasterFileAdapter) source).start();
198
                ((RasterFileAdapter) source).setTransparency(getTransparency());
199
        }
200

    
201
        /**
202
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
203
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
204
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
205
         */
206
        public void draw(BufferedImage image, Graphics2D g, ViewPort vp,
207
                Cancellable cancel,double scale) throws DriverException {
208
                if (isWithinScale(scale)){        
209
                try {
210
                        if(status!=null && firstLoad){
211
                                ((RasterFileAdapter) source).draw(image, g, vp, cancel);        
212
                                status.applyStatus(this);
213
                                firstLoad = false;
214
                        }
215
                
216
                        ((RasterFileAdapter) source).draw(image, g, vp, cancel);
217
                                                                        
218
                } catch (DriverIOException e) {
219
                        throw new DriverException(e);
220
                }
221

    
222
                if (getVirtualLayers() != null) {
223
                        getVirtualLayers().draw(image, g, vp, cancel,scale);
224
                }
225
                }
226
        }
227

    
228
        /**
229
         * Inserta la proyecci?n.
230
         *
231
         * @param proj Proyecci?n.
232
         */
233
        public void setProjection(IProjection proj) {
234
                super.setProjection(proj);
235

    
236
                if (source != null && source.getDriver() != null && source.getDriver() instanceof GeorreferencedRasterDriver) {
237
                        GeorreferencedRasterDriver geoDrv = (GeorreferencedRasterDriver) source.getDriver();
238

    
239
                        if (geoDrv.getProjection() == null) {
240
                                geoDrv.setProjection(proj);
241
                        }
242
                }
243
        }
244
        
245
        public void setTransparency(int trans) {
246
                super.setTransparency(trans);
247
                ((RasterFileAdapter) source).setTransparency(trans);
248
                // TODO LWS Guarradita para actualizar el MapControl con ApplyButton
249
                if (getFMap() != null)
250
                        getFMap().invalidate();
251
        }
252

    
253
        public int getTransparency() {
254
                return ((RasterFileAdapter) source).getTransparency();
255
        }
256
        
257
        /*
258
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
259
         */
260
        public Rectangle2D getFullExtent() throws DriverException {
261
                return ((RasterFileAdapter) source).getFullExtent();
262
        }
263

    
264
        /**
265
         * Obtiene el valor del pixel del Image en la posici?n x,y
266
         * @param x Posici?n x
267
         * @param y Posici?n y
268
         * @return valor de pixel
269
         */
270
        public int[] getPixel(double wcx, double wcy){
271
                return ((RasterFileAdapter) source).getPixel(wcx, wcy);
272
        }
273
        
274
        public double getMaxX(){
275
                try {
276
                        return this.getFullExtent().getMaxX();
277
                }catch(DriverException e){
278
                        return 0D;
279
                }
280
        }
281
        
282
        public double getMaxY(){
283
                try {
284
                        return this.getFullExtent().getMaxY();
285
                }catch(DriverException e){
286
                        return 0D;
287
                }
288
        }
289
        
290
        public double getMinX(){
291
                try {
292
                        return this.getFullExtent().getMinX();
293
                }catch(DriverException e){
294
                        return 0D;
295
                }
296
        }
297
        
298
        public double getMinY(){
299
                try {
300
                        return this.getFullExtent().getMinY();
301
                }catch(DriverException e){
302
                        return 0D;
303
                }
304
        }
305
        
306
        public double getHeight(){
307
                try {
308
                        return this.getFullExtent().getHeight();
309
                }catch(DriverException e){
310
                        return 0D;
311
                }
312
        }
313
        
314
        public double getWidth(){
315
                try {
316
                        return this.getFullExtent().getWidth();
317
                }catch(DriverException e){
318
                        return 0D;
319
                }
320
        }
321

    
322
        
323
        /* (non-Javadoc)
324
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(java.awt.Point)
325
         */
326
        public String queryByPoint(Point p) throws DriverException {
327
                String data = "<file:"+normalizeAsXMLTag(getName())+">\n";
328

    
329
                ArrayList attr = source.getAttributes();
330
                data += "  <raster\n";
331
                data += "    File=\""+((RasterFileAdapter) source).getFile()+"\"\n";
332
                for (int i=0; i<attr.size(); i++) {
333
                        Object [] a = (Object []) attr.get(i);
334

    
335
                        data += "    "+a[0].toString()+"=";
336
                        if (a[1].toString() instanceof String)
337
                                data += "\""+a[1].toString()+"\"\n";
338
                        else
339
                                data += a[1].toString()+"\n";
340
                }
341
                data += "    Point=\""+posX+" , "+posY+"\"\n";
342
                data += "    Point_WC=\""+posXWC+" , "+posYWC+"\"\n";
343
                data += "    RGB=\""+r+", "+g+", "+b+"\"\n";
344
                data += "  />\n";
345

    
346
                data += "</file:"+normalizeAsXMLTag(getName())+">\n";
347
                //System.out.println(data);
348
                return data;
349
        }
350
        
351
        /**
352
         * Filters a string for being suitable as XML Tag, erasing
353
         * all not alphabetic or numeric characters.
354
         * @param s
355
         * @return string normalized
356
         */
357
        public String normalizeAsXMLTag(String s) {
358
                return s.replaceAll("[^a-zA-Z0-9]","");
359
        }
360

    
361
        /**
362
         * Obtiene atributos a partir de un georasterfile
363
         * @return
364
         */
365
        public ArrayList getAttributes() {
366
                return source.getAttributes();
367
        }
368
        
369
        /**
370
         * @throws XMLException
371
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
372
         */
373
        public XMLEntity getXMLEntity() throws XMLException {
374
                XMLEntity xml = super.getXMLEntity();
375
        
376
                if (source instanceof RasterFileAdapter) {
377
                        xml.putProperty("file", ((RasterFileAdapter) source).getFile());
378
                }
379
        
380
                xml.putProperty("driverName", getSource().getDriver().getName());
381
                
382
                //Si no hay ning?n Status aplicamos el StatusLayerRaster que se usa por defecto
383
                if(status == null)
384
                        status = new StatusLayerRaster();
385
                
386
                status.getXMLEntity(xml, true, this);
387
                
388
                return xml;
389
        }
390
        
391
        public void setXMLEntity03(XMLEntity xml)
392
        throws XMLException {
393
                super.setXMLEntity(xml);
394
                try {
395
                        Driver d = LayerFactory.getDM().getDriver(
396
                                xml.getStringProperty("driverName"));
397
                        File f = new File(xml.getStringProperty("file"));
398
                        RasterAdapter adapter = new RasterFileAdapter(f);
399
                        adapter.setDriver(d);
400
                        setSource(adapter);
401
                        // Para notificar al adapter-driver cual es la proyecci?n.
402
                        setProjection(super.getProjection());
403
                } catch (DriverLoadException e) {
404
                        throw new XMLException(e);
405
                }
406
        }
407
        
408
        public void setXMLEntity(XMLEntity xml)
409
        throws XMLException {
410
                super.setXMLEntity(xml);
411
                try {
412
                        Driver d = LayerFactory.getDM().getDriver(
413
                                xml.getStringProperty("driverName"));
414
                        File f = new File(xml.getStringProperty("file"));
415
                        RasterAdapter adapter = new RasterFileAdapter(f);
416
                        adapter.setDriver(d);
417
                        setSource(adapter);
418
                        // Para notificar al adapter-driver cual es la proyecci?n.
419
                        setProjection(super.getProjection());
420
                        
421
                        //Inicializamos la clase a la que se usa por defecto para
422
                        //compatibilidad con proyectos antiguos
423
                        String claseStr = StatusLayerRaster.defaultClass;
424
                        if (xml.contains("raster.class")) {
425
                                claseStr = xml.getStringProperty("raster.class");
426
                        }
427
                        if(status!=null)
428
                                status.setXMLEntity(xml, this);
429
                        else{
430
                                
431
                                //Cuando cargamos un proyecto 
432
                                
433
                                if(claseStr!=null && !claseStr.equals("")){
434
                                        try{
435
                                                Class clase = Class.forName(claseStr);
436
                                                Constructor constr = clase.getConstructor(null);
437
                                                status = (StatusRasterInterface)constr.newInstance(null);
438
                                                if(status!=null)
439
                                                        status.setXMLEntity(xml, this);
440
                                        }catch(ClassNotFoundException exc){
441
                                                exc.printStackTrace();
442
                                        }catch(InstantiationException exc){
443
                                                exc.printStackTrace();
444
                                        }catch(IllegalAccessException exc){
445
                                                exc.printStackTrace();
446
                                        }catch(NoSuchMethodException exc){
447
                                                exc.printStackTrace();
448
                                        }catch(InvocationTargetException exc){
449
                                                exc.printStackTrace();
450
                                        }                                        
451
                                }
452
                        }
453
                        firstLoad = true;
454
                        
455
                        
456
                } catch (DriverLoadException e) {
457
                        throw new XMLException(e);
458
                }
459
        }
460

    
461
        /* (non-Javadoc)
462
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort, com.iver.cit.gvsig.fmap.operations.Cancellable)
463
         */
464
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
465
                throws DriverException {
466
                
467
                if (isVisible() && isWithinScale(scale)){        
468
                isPrinting = true;
469
                if (!mustTilePrint) {
470
                        draw(null, g, viewPort, cancel,scale);
471
                } else {
472
                // Para no pedir imagenes demasiado grandes, vamos
473
                // a hacer lo mismo que hace EcwFile: chunkear.
474
                // Llamamos a drawView con cuadraditos m?s peque?os
475
                // del BufferedImage ni caso, cuando se imprime viene con null
476
                        Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipRect());
477
                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
478
                        
479
                        //Si es la primera lectura salvamos los valores de m?ximo y m?nimo para la aplicaci?n
480
                        //de realce si la imagen es de 16 bits.
481
                        
482
                        RasterStats stats = getSource().getFilterStack().getStats();
483
                        if(stats != null)
484
                                stats.history.add(stats.new History(getName(), stats.minBandValue, stats.maxBandValue, stats.secondMinBandValue, stats.secondMaxBandValue));        
485
                                        
486
                        
487
                        for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
488
                            // Parte que dibuja
489
                            try {
490
                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
491
                                draw(null, g, vp, cancel,scale);
492
                                } catch (NoninvertibleTransformException e) {
493
                                        // TODO Auto-generated catch block
494
                                        e.printStackTrace();
495
                                }
496
                }
497
                        
498
                        if(stats != null){
499
                                getSource().getFilterStack().getStats().history.clear();
500
                                stats = getSource().getFilterStack().getStats();
501
                        }
502
                                                
503
                }
504
            isPrinting = false;
505
                }
506
        }
507

    
508
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
509
                throws DriverException {                
510
                // Para no pedir imagenes demasiado grandes, vamos
511
                // a hacer lo mismo que hace EcwFile: chunkear.
512
                // Llamamos a drawView con cuadraditos m?s peque?os
513
                // del BufferedImage ni caso, cuando se imprime viene con null
514
                
515
                int numW, numH;
516
                int stepX, stepY;
517
                int xProv, yProv, wProv, hProv;
518
                double xProvD, yProvD, wProvD, hProvD;
519
                int A = 1500; 
520
                int H = 1500;
521
                int altoAux, anchoAux;
522
                
523
                AffineTransform mat = (AffineTransform) viewPort.getAffineTransform().clone();
524
                
525
                // Vamos a hacerlo en trozos de AxH
526
                Rectangle r = g.getClipRect();
527
                numW = (int) (r.width) / A;
528
                numH = (int) (r.height) / H;                
529
                
530
                
531
                double[] srcPts = new double[8];
532
                double[] dstPts= new double[8];
533

    
534
                yProv = (int) r.y;
535
                for (stepY=0; stepY < numH+1; stepY++)
536
                {
537
                        if ((yProv + H) > r.getMaxY()) 
538
                                altoAux = (int) r.getMaxY() - yProv;
539
                        else
540
                                altoAux = H;
541
                                                
542
                        xProv = (int) r.x;
543
                        for (stepX=0; stepX < numW+1; stepX++)                                
544
                        {                        
545
                                    if ((xProv + A) > r.getMaxX()) 
546
                                            anchoAux = (int) r.getMaxX() - xProv;
547
                                    else
548
                                            anchoAux = A;
549
                                
550
                                Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
551
                                
552
                                // Parte que dibuja
553
                                srcPts[0] = xProv;
554
                                srcPts[1] = yProv;
555
                                srcPts[2] = xProv + anchoAux+1;
556
                                srcPts[3] = yProv;
557
                                srcPts[4] = xProv + anchoAux+1;
558
                                srcPts[5] = yProv + altoAux+1;
559
                                srcPts[6] = xProv;
560
                                srcPts[7] = yProv + altoAux+1;
561
                                
562
                                try {
563
                                                mat.inverseTransform(srcPts, 0, dstPts, 0, 4);
564
                                        Rectangle2D.Double rectCuadricula = new Rectangle2D.Double(
565
                                                        dstPts[0], dstPts[1],
566
                                                                dstPts[2] - dstPts[0], dstPts[5]-dstPts[3]); 
567
                                        Extent extent = new Extent(rectCuadricula);
568
                                        
569
                                        Dimension tam = new Dimension(anchoAux+1, altoAux+1);
570
                                        ViewPort vp = viewPort.cloneViewPort();
571
                                        vp.setImageSize(tam);
572
                                        vp.setExtent(rectCuadricula);
573
                                        vp.setAffineTransform(mat);
574
                                        // ViewPortData vp = new ViewPortData(getProjection(), extent, tam);
575
                                        // vp.setMat(mat);
576
                                        // rasterList.draw(g2, vp);
577
                                                                                
578
                                        /*System.out.println("FLyrRaster.print(): fila "+stepX+" de "
579
                                                + numW + " , col "+stepY+" de " + numH + 
580
                                                "\n, Extent = "+vp.getExtent() + " imageSize: "
581
                                                + tam);*/
582
                                        draw(null, g, vp, cancel,scale);
583
                                                
584
                                        } catch (NoninvertibleTransformException e) {
585
                                                // TODO Auto-generated catch block
586
                                                e.printStackTrace();
587
                                        }
588
                                // Fin parte que dibuja
589
                                        xProv = xProv + A;        
590
                        }                        
591
                        yProv = yProv + H;
592
                }  
593
                
594
        }
595
        
596
        /**
597
         * A?ade un fichero a la capa raster
598
         * @param fileName Nombre del fichero
599
         */
600
        public void addFiles(String fileName){
601
                ((RasterFileAdapter) source).addFile(fileName);
602
        }
603
        
604
        /**
605
         * Elimina un fichero a la capa raster
606
         * @param fileName Nombre del fichero
607
         */
608
        public void delFile(String fileName){
609
                ((RasterFileAdapter) source).delFile(fileName);
610
        }
611
        
612
        /* (non-Javadoc)
613
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#setBand(int, int)
614
         */
615
        public void setBand(int flag, int nBand) {
616
                this.getSource().setBand(flag, nBand);
617
        }
618
        
619
        /**
620
         * Borra de la lista de listeners el que se pasa como par?metro.
621
         *
622
         * @param o LayerListener a borrar.
623
         *
624
         * @return True si ha sido correcto el borrado del Listener.
625
         */
626
        public boolean removeLayerListener(LayerListener o) {
627
                if(this.isRemoveRasterFlag()){
628
                        /*try{
629
                                ((RasterFileAdapter) source).stop();
630
                        }catch(DriverIOException exc){
631
                                
632
                        }*/
633
                        this.setRemoveRasterFlag(true);
634
                }
635
                return super.layerListeners.remove(o);
636
        }
637
        
638
        /**
639
         * @return Returns the removeRasterFlag.
640
         */
641
        public boolean isRemoveRasterFlag() {
642
                return removeRasterFlag;
643
        }
644
        
645
        /**
646
         * Asigna el valor del flag que dice si destruimos la memoria del raster
647
         * al eliminarlo del TOC o  no.
648
         * @param removeRasterFlag The removeRasterFlag to set.
649
         */
650
        public void setRemoveRasterFlag(boolean removeRasterFlag) {
651
                this.removeRasterFlag = removeRasterFlag;
652
        }
653
}