Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrRaster.java @ 4234

History | View | Annotate | Download (17.6 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
         * Inserta el RasterAdapter.
105
         *
106
         * @param ra RasterAdapter.
107
         */
108
        public void setSource(RasterAdapter ra) {
109
                source = ra;
110
        }
111

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

    
188
        /**
189
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
190
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
191
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
192
         */
193
        public void draw(BufferedImage image, Graphics2D g, ViewPort vp,
194
                Cancellable cancel,double scale) throws DriverException {
195
                if (isWithinScale(scale)){        
196
                try {
197
                        if(status!=null && firstLoad){
198
                                ((RasterFileAdapter) source).draw(image, g, vp, cancel);        
199
                                status.applyStatus(this);
200
                                firstLoad = false;
201
                        }
202
                
203
                        ((RasterFileAdapter) source).draw(image, g, vp, cancel);
204
                                                                        
205
                } catch (DriverIOException e) {
206
                        throw new DriverException(e);
207
                }
208

    
209
                if (getVirtualLayers() != null) {
210
                        getVirtualLayers().draw(image, g, vp, cancel,scale);
211
                }
212
                }
213
        }
214

    
215
        /**
216
         * Inserta la proyecci?n.
217
         *
218
         * @param proj Proyecci?n.
219
         */
220
        public void setProjection(IProjection proj) {
221
                super.setProjection(proj);
222

    
223
                if (source != null && source.getDriver() != null && source.getDriver() instanceof GeorreferencedRasterDriver) {
224
                        GeorreferencedRasterDriver geoDrv = (GeorreferencedRasterDriver) source.getDriver();
225

    
226
                        if (geoDrv.getProjection() == null) {
227
                                geoDrv.setProjection(proj);
228
                        }
229
                }
230
        }
231
        
232
        public void setTransparency(int trans) {
233
                super.setTransparency(trans);
234
                ((RasterFileAdapter) source).setTransparency(trans);
235
                // TODO LWS Guarradita para actualizar el MapControl con ApplyButton
236
                if (getFMap() != null)
237
                        getFMap().invalidate();
238
        }
239

    
240
        public int getTransparency() {
241
                return ((RasterFileAdapter) source).getTransparency();
242
        }
243
        
244
        /*
245
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
246
         */
247
        public Rectangle2D getFullExtent() throws DriverException {
248
                return ((RasterFileAdapter) source).getFullExtent();
249
        }
250

    
251
        /**
252
         * Obtiene el valor del pixel del Image en la posici?n x,y
253
         * @param x Posici?n x
254
         * @param y Posici?n y
255
         * @return valor de pixel
256
         */
257
        public int[] getPixel(double wcx, double wcy){
258
                return ((RasterFileAdapter) source).getPixel(wcx, wcy);
259
        }
260
        
261
        public double getMaxX(){
262
                try {
263
                        return this.getFullExtent().getMaxX();
264
                }catch(DriverException e){
265
                        return 0D;
266
                }
267
        }
268
        
269
        public double getMaxY(){
270
                try {
271
                        return this.getFullExtent().getMaxY();
272
                }catch(DriverException e){
273
                        return 0D;
274
                }
275
        }
276
        
277
        public double getMinX(){
278
                try {
279
                        return this.getFullExtent().getMinX();
280
                }catch(DriverException e){
281
                        return 0D;
282
                }
283
        }
284
        
285
        public double getMinY(){
286
                try {
287
                        return this.getFullExtent().getMinY();
288
                }catch(DriverException e){
289
                        return 0D;
290
                }
291
        }
292
        
293
        public double getHeight(){
294
                try {
295
                        return this.getFullExtent().getHeight();
296
                }catch(DriverException e){
297
                        return 0D;
298
                }
299
        }
300
        
301
        public double getWidth(){
302
                try {
303
                        return this.getFullExtent().getWidth();
304
                }catch(DriverException e){
305
                        return 0D;
306
                }
307
        }
308

    
309
        
310
        /* (non-Javadoc)
311
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(java.awt.Point)
312
         */
313
        public String queryByPoint(Point p) throws DriverException {
314
                String data = "<file:"+normalizeAsXMLTag(getName())+">\n";
315

    
316
                ArrayList attr = source.getAttributes();
317
                data += "  <raster\n";
318
                data += "    File=\""+((RasterFileAdapter) source).getFile()+"\"\n";
319
                for (int i=0; i<attr.size(); i++) {
320
                        Object [] a = (Object []) attr.get(i);
321

    
322
                        data += "    "+a[0].toString()+"=";
323
                        if (a[1].toString() instanceof String)
324
                                data += "\""+a[1].toString()+"\"\n";
325
                        else
326
                                data += a[1].toString()+"\n";
327
                }
328
                data += "    Point=\""+posX+" , "+posY+"\"\n";
329
                data += "    Point_WC=\""+posXWC+" , "+posYWC+"\"\n";
330
                data += "    RGB=\""+r+", "+g+", "+b+"\"\n";
331
                data += "  />\n";
332

    
333
                data += "</file:"+normalizeAsXMLTag(getName())+">\n";
334
                //System.out.println(data);
335
                return data;
336
        }
337
        
338
        /**
339
         * Filters a string for being suitable as XML Tag, erasing
340
         * all not alphabetic or numeric characters.
341
         * @param s
342
         * @return string normalized
343
         */
344
        public String normalizeAsXMLTag(String s) {
345
                return s.replaceAll("[^a-zA-Z0-9]","");
346
        }
347

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

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

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

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