Statistics
| Revision:

svn-gvsig-desktop / branches / v02_desarrollo / libraries / libCq CMS for java.old / src / org / cresques / px / PxRaster.java @ 1533

History | View | Annotate | Download (16.6 KB)

1
/*
2
 * PxRaster.java
3
 */
4
package org.cresques.px;
5

    
6
import java.awt.Color;
7
import java.awt.Component;
8
import java.awt.Graphics2D;
9
import java.awt.Image;
10
import java.awt.geom.GeneralPath;
11
import java.awt.geom.Point2D;
12
import java.awt.image.BufferedImage;
13
import java.awt.image.DataBuffer;
14
import java.awt.image.ImageObserver;
15
import java.util.Date;
16
import java.util.Vector;
17

    
18
import org.cresques.cts.ICoordTrans;
19
import org.cresques.cts.IProjection;
20
import org.cresques.geo.Projected;
21
import org.cresques.geo.ViewPortData;
22
import org.cresques.io.GdalFile;
23
import org.cresques.io.GeoRasterFile;
24
import org.cresques.io.RasterBuf;
25

    
26
public class PxRaster extends PxObj implements Projected {
27
        protected GeoRasterFile geoFile = null;
28
        protected ImageObserver component = null;
29
        Vector pts = null;
30
        // Soporte para n bandas, visibles de 3 en 3, en ficheros separados
31
        protected GeoRasterFile [] colorBand = null;
32
        protected int rBand = 1, gBand = 2, bBand = 3;
33
        
34
        int [] minBandValue = {Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE};
35
        int [] maxBandValue = {Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE};
36

    
37
        int transparente = 0x10ffff80;
38

    
39
        String vName = null;
40
        protected boolean pintaMarco = false; //true;
41
        IProjection proj = null;
42
        protected Extent extentOrig = null;
43
        ICoordTrans rp = null;
44
        
45
        /**
46
         * Constructor.
47
         * @param component
48
         */
49
        public PxRaster(ImageObserver component) {
50
                this.component = component;
51
        }
52
                
53
        public PxRaster(IProjection proj, String fname, ImageObserver component) {
54
                geoFile = GeoRasterFile.openFile(proj, fname);//loadECW(fname);
55
                geoFile.setUpdatable((Component) component);
56
                this.proj = proj;
57
                this.component = component;
58
                setExtent(geoFile.getExtent());
59
                geoFile.setView(geoFile.getExtent());
60
                extentOrig = extent;
61
                if (geoFile.getBandCount()>2) {
62
                        setBand(GeoRasterFile.RED_BAND, 0);
63
                        setBand(GeoRasterFile.GREEN_BAND, 1);
64
                        setBand(GeoRasterFile.BLUE_BAND, 2);
65
                } else {
66
                        setBand(GeoRasterFile.RED_BAND|GeoRasterFile.GREEN_BAND|GeoRasterFile.BLUE_BAND, 0);
67
                }
68
        }
69
        
70
        /*public PxRaster(String fname, ImageObserver component, Extent view) {
71
                geoFile = GeoRasterFile.openFile(null, fname);//loadECW(fname);
72
                this.component = component;
73
                setExtent(geoFile.getExtent());
74
                geoFile.setView(view);
75
                extentOrig = extent;
76
                
77
                //double x = 680800,y = 4128600;
78
                //setView(new Extent(x, y, x+4200, y-4200),"Huelva capital");
79
        }*/
80
        
81
        public PxRaster(IProjection proj, String [] fnames, ImageObserver component) {
82
                this.proj = proj;
83
                this.component = component;
84
                colorBand = new GeoRasterFile[fnames.length];
85
                for (int i=0; i<colorBand.length; i++) {
86
                    colorBand[i] = GeoRasterFile.openFile(proj, fnames[i]);//loadECW(fname);
87
                    colorBand[i].setUpdatable((Component) component);
88
                    setExtent(colorBand[i].getExtent());
89
                    colorBand[i].setView(colorBand[i].getExtent());
90
                }
91
                geoFile = colorBand[0];
92
                extentOrig = extent;
93
                if (fnames.length >= 3 || geoFile.getBandCount()>2) {
94
                        setBand(GeoRasterFile.RED_BAND, 0);
95
                        setBand(GeoRasterFile.GREEN_BAND, 1);
96
                        setBand(GeoRasterFile.BLUE_BAND, 2);
97
                } else {
98
                        setBand(GeoRasterFile.RED_BAND|GeoRasterFile.GREEN_BAND|GeoRasterFile.BLUE_BAND, 0);
99
                }
100
        }
101
        
102
        public PxRaster(GeoRasterFile eFile, ImageObserver component, Extent view) {
103
                geoFile = eFile;//loadECW(fname);
104
                geoFile.setUpdatable((Component) component);
105
                setProjection(geoFile.getProjection());
106
                this.component = component;
107

    
108
                setExtent(geoFile.getExtent());
109
                geoFile.setView(view); //geoFile.getExtent());
110
                extentOrig = extent;
111
                if (geoFile.getBandCount()>2) {
112
                        setBand(GeoRasterFile.RED_BAND, 0);
113
                        setBand(GeoRasterFile.GREEN_BAND, 1);
114
                        setBand(GeoRasterFile.BLUE_BAND, 2);
115
                } else {
116
                        setBand(GeoRasterFile.RED_BAND|GeoRasterFile.GREEN_BAND|GeoRasterFile.BLUE_BAND, 0);
117
                }
118
        }
119
        
120
        public int getBandCount() { return geoFile.getBandCount(); }
121
        
122
        public GeoRasterFile [] getFiles() {
123
                if (colorBand != null)
124
                        return colorBand;
125
                
126
                GeoRasterFile [] ret = {geoFile};
127
                return ret;
128
        }
129
        
130
        /**
131
         * Asocia un colorBand al rojo, verde o azul.
132
         * @param flag cual (o cuales) de las bandas.
133
         * @param nBand        que colorBand
134
         */
135
        
136
        public void setBand(int flag, int nBand) {
137
                if (colorBand != null) {
138
                        if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND)
139
                                rBand = nBand;
140
                        else if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND)
141
                                gBand = nBand;
142
                        else if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND)
143
                                bBand = nBand;
144
                } else
145
                        geoFile.setBand(flag, nBand);
146
        }
147

    
148
        /**
149
         * Devuelve el colorBand activo en la banda especificada.
150
         * @param flag banda.
151
         */
152
        
153
        public int getBand(int flag) {
154
                if (colorBand != null) {
155
                        if (flag == GeoRasterFile.RED_BAND)
156
                                return rBand;
157
                        else if (flag == GeoRasterFile.GREEN_BAND)
158
                                return gBand;
159
                        else if (flag == GeoRasterFile.BLUE_BAND)
160
                                return bBand;
161
                        else
162
                                return -1;
163
                } else
164
                        return geoFile.getBand(flag);
165
        }
166

    
167
        public void setDrawBorder(boolean pm) { pintaMarco = pm; }
168
        
169
        public String getFName() {
170
                return geoFile.getName();
171
        }
172
        
173
        /**
174
         * Devuelve la anchura total del fichero, en pixeles.
175
         * @return ancho en pixeles
176
         */
177
        public int getFWidth() {
178
                return geoFile.getWidth();
179
        }
180
        
181
        /**
182
         * Devuelve la altura total del fichero, en pixeles.
183
         * @return alto en pixeles
184
         */
185
        public int getFHeight() {
186
                return geoFile.getHeight();
187
        }
188
        
189
        public void setTransparency(boolean t) {geoFile.setTransparency(t);}
190
        public void setTransparency(int t) {geoFile.setTransparency(t);}
191
        
192
        public int getAlpha() { return geoFile.getAlpha(); }
193
        
194
        public void setExtent(Extent e) {
195
                super.extent = e;
196
                pts = new Vector();
197
                pts.add(proj.createPoint(e.minX(), e.minY()));
198
                pts.add(proj.createPoint(e.maxX(), e.minY()));
199
                pts.add(proj.createPoint(e.maxX(), e.maxY()));
200
                pts.add(proj.createPoint(e.minX(), e.maxY()));
201
        }
202
        
203
        /**
204
         * Cambia la vista (viewport) sobre el raster.
205
         * 
206
         * @param v
207
         * @param vName
208
         */
209
        public void setView(Extent v, String vName) {
210
                geoFile.setView(v);
211
                this.vName = vName;
212
        }
213
        
214
        /**
215
         * Obtiene la escala.
216
         * 
217
         * @param width
218
         * @param height
219
         * @return
220
         */
221
        
222
        public double[] getScale(int width, int height) {
223
                double scale[] = new double[2];
224
                scale[0] = ((double) width) /geoFile.getView().width();                
225
                scale[1] = ((double) height)/geoFile.getView().height();                
226
                return scale;
227
        }
228
        
229
        /**
230
         * 'Normaliza' la vista en funci?n del extent del raster.
231
         * 
232
         * @param mat
233
         * @param sz
234
         */
235

    
236
        protected void calculateNewView(Extent sz) {
237
                double vx = sz.minX(), vy = sz.minY(), vx2 = sz.maxX(), vy2 = sz.maxY();
238
                if (sz.minX() < extent.minX()) vx = extent.minX();
239
                if (sz.minY() < extent.minY()) vy = extent.minY();
240
                if (sz.maxX() > extent.maxX()) vx2 = extent.maxX();
241
                if (sz.maxY() > extent.maxY()) vy2 = extent.maxY();
242
                if (colorBand != null) { // multiBands
243
                        for (int i=0; i<colorBand.length; i++)
244
                                colorBand[i].setView(new Extent(vx, vy, vx2, vy2));
245
                } else if (geoFile != null) { // Una sola banda
246
                        geoFile.setView(new Extent(vx, vy, vx2, vy2));
247
                } else { // no cargada
248
                        System.err.println("PxRaster.calculateNewView(): Foto no cargada.");
249
                }
250
        }
251

    
252
        /**
253
         * Dibuja el raster
254
         */        
255

    
256
        public void draw(Graphics2D g, ViewPortData vp) {
257
                Image geoImage = null;
258
                long t2, t1 = new Date().getTime();
259
                System.out.println("PxRaster.draw(): vp.extent = "+ vp.getExtent());
260
                System.out.println("PxRaster.draw():    extent = "+ getExtent());
261
                if (vp.getExtent().minX()> extent.maxX()) return;
262
                if (vp.getExtent().minY()> extent.maxY()) return;
263
                if (vp.getExtent().maxX()< extent.minX()) return;
264
                if (vp.getExtent().maxY()< extent.minY()) return;
265
                calculateNewView(vp.getExtent()); 
266
                Extent v = geoFile.getView();
267
                double x = v.minX();
268
                double y = v.minY();
269
                double w = v.width();
270
                double h = v.height();
271
                System.out.println("Pinto PxRaster:" + v);
272
                
273
                double scalex = vp.mat.getScaleX()        /* g.getTransform().getScaleX()*/ ,
274
                        scaley = vp.mat.getScaleY()                /* g.getTransform().getScaleY() */;
275
                int wImg = (int) Math.abs(w*scalex)+1, hImg = (int) Math.abs(h*scaley)+1;
276
                System.out.println("Sz=("+wImg+","+hImg+"); scale=("+scalex+","+scaley+")");
277
                if (wImg <= 0 || hImg <= 0) return;
278
                
279
                Point2D.Double pt = new Point2D.Double(x, y+h);
280
                try {
281
                        System.out.println("Dibujando PxRaster: pt0 = "+pt);
282
                        vp.mat.transform(pt, pt);
283
                        System.out.println("Dibujando PxRaster: pt1 = "+pt);
284
                        if (colorBand == null && geoFile instanceof GdalFile &&
285
                                (geoFile.getDataType() != DataBuffer.TYPE_BYTE)) {
286
                                System.out.println("PxRaster: Has dado con un Raster de 16 bits");
287
                                System.out.println("Dibujando PxRaster sz=("+wImg+","+hImg+"...");
288
                                RasterBuf raster = ((GdalFile) geoFile).getRaster(wImg, hImg, rp);
289
                                t2 = new Date().getTime();
290
                                System.out.println("Dibujando PxRaster: "+(t2-t1)/1000D+", secs. Obteniendo"); t1 = t2;
291
                                geoImage = renderizeRaster(raster);
292
                                t2 = new Date().getTime();
293
                                System.out.println("Dibujando PxRaster: "+(t2-t1)/1000D+", secs. Filtrando/Renderizando");t1 = t2;
294

    
295
                                g.drawImage(geoImage, (int) Math.round(pt.getX()), (int) Math.round(pt.getY()), component);
296
                                t2 = new Date().getTime();
297
                                System.out.println("Dibujando PxRaster: "+(t2-t1)/1000D+", secs. Dibujando");
298
                        } else if (colorBand != null) { // multiBands
299
                                System.out.println("Dibujando PxRaster (Multifile) ...");
300
                            //if (doTransparency)
301
                            //geoImage = new BufferedImage(wImg, hImg, BufferedImage.TYPE_INT_ARGB);
302
                            //else
303
                            //        geoImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
304
                        geoImage = colorBand[rBand].updateImage(wImg, hImg, rp); //, geoImage, GeoRasterFile.RED_BAND);
305
                        geoImage = colorBand[gBand].updateImage(wImg, hImg, rp, geoImage, GeoRasterFile.GREEN_BAND);
306
                        geoImage = colorBand[bBand].updateImage(wImg, hImg, rp, geoImage, GeoRasterFile.BLUE_BAND);
307

    
308
                                g.drawImage(geoImage, (int) Math.round(pt.getX()), (int) Math.round(pt.getY()), component);
309
                                t2 = new Date().getTime();
310
                                System.out.println("Dibujando PxRaster: "+(t2-t1)/1000D+", secs.");
311
                        
312
                        } else if (geoFile != null) { // Una sola banda
313
                        geoImage = geoFile.updateImage(wImg, hImg, rp);
314
                                System.out.println("Dibujando PxRaster sz=("+wImg+","+hImg+"...");
315

    
316
                                g.drawImage(geoImage, (int) Math.round(pt.getX()), (int) Math.round(pt.getY()), component);
317
                                t2 = new Date().getTime();
318
                                System.out.println("Dibujando PxRaster: "+(t2-t1)/1000D+", secs.");
319
                        } else { // no cargada
320
                                System.err.println("Dibujando PxRaster: Foto no cargada.");
321
                        }
322
                } catch (Exception e) {
323
                        e.printStackTrace();
324
                };
325

    
326
                if (pintaMarco) {
327
                        drawMarco(g, vp);
328
                }
329
        }
330
        
331
        /**
332
         * Filtro para raster. Ancestro de todos los filtros.
333
         * @author Luis W. Sevilla (sevilla_lui@gva.es)
334
         */
335
        abstract class RasterFilter {
336
                protected RasterBuf raster = null;
337
                protected int [] px = new int[3];
338
                private int height = 0;
339
                private int width = 0;
340
                
341
                public RasterFilter(RasterBuf raster) {
342
                        this.raster = raster;
343
                        height = raster.getHeight();
344
                        width = raster.getWidth();
345
                }
346
                
347
                public void execute() {
348
                        for (int y=0; y<height; y++)
349
                                for (int x=0; x<width; x++) {
350
                                        process(x, y);
351
                                }
352
                }
353
                
354
                abstract public void process(int x, int y);
355
        }
356
        
357
        /**
358
         * Calcula el m?ximo y el m?nimo de un raster.
359
         * @author Luis W. Sevilla (sevilla_lui@gva.es)
360
         */
361
        class ComputeMinMaxFilter extends RasterFilter {
362
                private int [] min = {Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE};
363
                private int [] max = {Integer.MIN_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE};
364
                
365
                public ComputeMinMaxFilter(RasterBuf raster, int [] min, int [] max) {
366
                        super(raster);
367
                        this.raster = raster;
368
                        this.min = new int[min.length];
369
                        this.max = new int[max.length];
370
                        for (int i=0; i<min.length; i++) {
371
                                this.min[i] = min[i];
372
                                this.max[i] = max[i];
373
                        }
374
                        execute();
375
                }
376
                
377
                public void process(int x, int y) {
378
                        raster.getPixelShort(x, y, px);
379
                        for (int i=0; i<3; i++) {
380
                                min[i] = Math.min(min[i], px[i]);
381
                                max[i] = Math.max(max[i], px[i]);
382
                        }
383
                }
384

    
385
                public int getMin(int bandNr) { return min[bandNr]; }
386

    
387
                public int getMax(int bandNr) { return max[bandNr]; }
388
        }
389
        
390
        /**
391
         * Realzado Lineal (Amplitude Rescaling).
392
         * @author Luis W. Sevilla (sevilla_lui@gva.es)
393
         */
394
        class LinearEnhancementFilter extends RasterFilter {
395
                private double [] scale = new double[3];
396
                private double [] offset = new double[3];
397
                public LinearEnhancementFilter(RasterBuf raster, int [] min, int [] max) {
398
                        super(raster);
399
                        for (int i=0; i<3; i++) {
400
                                scale[i] = 255D/(max[i]-min[i]);
401
                                offset[i] = (255D*min[i])/(min[i]-max[i]);
402
                        }
403
                        execute();
404
                }
405

    
406
                public void process(int x, int y) {
407
                        raster.getPixelShort(x, y, px);
408
                        px[0] = (((int) (((double)px[0])*scale[0] + offset[0])) & 0xff);
409
                        px[1] = (((int) (((double)px[1])*scale[1] + offset[1])) & 0xff);
410
                        px[2] = (((int) (((double)px[2])*scale[2] + offset[2])) & 0xff);
411
                        raster.setPixelShort(x, y, px);
412
                }
413
        }
414
        
415
        /**
416
         * Renderiza el raster.
417
         * @author Luis W. Sevilla (sevilla_lui@gva.es)
418
         */
419
        
420
        class RasterToImageFilter extends RasterFilter {
421
                private BufferedImage image;
422
                private int alpha;
423
                private int rgb;
424
                public RasterToImageFilter(RasterBuf raster, int a) {
425
                        super(raster);
426
                        this.alpha = (a & 0xff) << 24;
427
                        image = new BufferedImage(raster.getWidth(), raster.getHeight(), BufferedImage.TYPE_INT_ARGB);
428
                        execute();
429
                }
430
                
431
                /* (non-Javadoc)
432
                 * @see org.cresques.px.PxRaster.RasterFilter#process(int, int)
433
                 */
434
                public void process(int x, int y) {
435
                        raster.getPixelShort(x, y, px);
436
                        rgb = alpha | ((px[0] & 0xff) << 16) |
437
                                        ((px[1] & 0xff) << 8) | (px[2] & 0xff);
438
                        
439
                        image.setRGB(x, y, rgb);
440
                }
441
                
442
                public Image getImage() { return image; }
443
        }
444
        
445
        public Image renderizeRaster(RasterBuf raster) {
446
                ComputeMinMaxFilter filter = 
447
                        new ComputeMinMaxFilter(raster, minBandValue, maxBandValue);
448
                for (int i=0; i<3; i++) {
449
                        minBandValue[i] = filter.getMin(i);
450
                        maxBandValue[i] = filter.getMax(i);
451
                }
452

    
453
                LinearEnhancementFilter lEFilter = 
454
                        new LinearEnhancementFilter(raster, minBandValue, maxBandValue);
455

    
456
                Image image = new RasterToImageFilter(raster, getAlpha()).getImage();
457
                
458
                for (int i=0; i<3; i++)
459
                        System.out.println("  Banda ["+i+"]: "+minBandValue[i]+"..."+maxBandValue[i]);
460
                return image;
461
        }
462
        
463
        public void drawMarco(Graphics2D g, ViewPortData vp) {
464
//                Color color = new Color(255,222,165,128), fillColor = new Color(255,214,132,128);
465
                Color color = new Color(128,128,128), fillColor = new Color(255,220,220,0x20);
466
                GeneralPath gp = newGP(vp);
467
                g.setColor(fillColor);
468
                g.fill(gp);
469
                g.setColor(color);
470
                g.draw(gp);
471
        }
472
        
473
        private GeneralPath newGP(ViewPortData vp) {
474
                //if (gp != null) return;
475
                GeneralPath gp = new GeneralPath();
476
                Point2D.Double pt0 = new Point2D.Double(0.0, 0.0);
477
                Point2D.Double pt1 = new Point2D.Double(0.0, 0.0);
478
                Point2D.Double pt2 = new Point2D.Double(0.0, 0.0);
479
                Point2D.Double pt3 = new Point2D.Double(0.0, 0.0);
480
                vp.mat.transform((Point2D) pts.get(0), pt0);
481
                vp.mat.transform((Point2D) pts.get(1), pt1);
482
                vp.mat.transform((Point2D) pts.get(2), pt2);
483
                vp.mat.transform((Point2D) pts.get(3), pt3);
484
                // Aspa desde el extent
485
                gp.moveTo( (float) pt0.getX(), (float) pt0.getY() );
486
                gp.lineTo( (float) pt2.getX(), (float) pt2.getY() );
487
                gp.moveTo( (float) pt1.getX(), (float) pt1.getY() );
488
                gp.lineTo( (float) pt3.getX(), (float) pt3.getY() );
489
                // Extent
490
                gp.moveTo( (float) pt0.getX(), (float) pt0.getY() );
491
                gp.lineTo( (float) pt1.getX(), (float) pt1.getY() );
492
                gp.lineTo( (float) pt2.getX(), (float) pt2.getY() );
493
                gp.lineTo( (float) pt3.getX(), (float) pt3.getY() );
494
                if (extentOrig != extent) {
495
                        gp.lineTo( (float) pt0.getX(), (float) pt0.getY() );
496
                        Vector pts = new Vector();
497
                        pts.add(proj.createPoint(extentOrig.minX(), extentOrig.minY()));
498
                        pts.add(proj.createPoint(extentOrig.maxX(), extentOrig.minY()));
499
                        pts.add(proj.createPoint(extentOrig.maxX(), extentOrig.maxY()));
500
                        pts.add(proj.createPoint(extentOrig.minX(), extentOrig.maxY()));
501

    
502
                        vp.mat.transform((Point2D) pts.get(0), pt0);
503
                        vp.mat.transform((Point2D) pts.get(1), pt1);
504
                        vp.mat.transform((Point2D) pts.get(2), pt2);
505
                        vp.mat.transform((Point2D) pts.get(3), pt3);
506
                        gp.moveTo( (float) pt0.getX(), (float) pt0.getY() );
507
                        gp.lineTo( (float) pt1.getX(), (float) pt1.getY() );
508
                        gp.lineTo( (float) pt2.getX(), (float) pt2.getY() );
509
                        gp.lineTo( (float) pt3.getX(), (float) pt3.getY() );
510
                }
511
                gp.closePath();
512
                return gp;
513
        }
514

    
515
        public IProjection getProjection() { return proj; }
516
        public void setProjection(IProjection p) { proj = p; }
517

    
518
        public void reProject(ICoordTrans rp) {
519
                this.rp = rp.getInverted();
520
                System.out.println("PxRaster: reProject()");
521
                //geoFile.reProject(rp);
522
                Vector savePts = pts;
523

    
524
                pts = new Vector();
525
                extent = new Extent();
526
                Point2D ptDest = null;
527
                for (int i=0; i<savePts.size(); i++) {
528
                        ptDest = rp.getPDest().createPoint(0.0,0.0);
529
                        ptDest = rp.convert((Point2D) savePts.get(i), ptDest);
530
                        pts.add(ptDest);
531
                        extent.add(ptDest);
532
                }
533
                setProjection(rp.getPDest());
534
        }
535
}