Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / MosaicProcess.java @ 20787

History | View | Annotate | Download (17 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Instituto de Desarrollo Regional 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 Iba?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
 *   Instituto de Desarrollo Regional (Universidad de Castilla La-Mancha)
34
 *   Campus Universitario s/n
35
 *   02071 Alabacete
36
 *   Spain
37
 *
38
 *   +34 967 599 200
39
 */
40

    
41
package org.gvsig.remotesensing.mosaic.process;
42

    
43
import java.awt.geom.AffineTransform;
44
import java.io.File;
45
import java.io.IOException;
46

    
47
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
48
import org.gvsig.raster.RasterProcess;
49
import org.gvsig.raster.buffer.BufferFactory;
50
import org.gvsig.raster.buffer.RasterBuffer;
51
import org.gvsig.raster.buffer.RasterBufferInvalidException;
52
import org.gvsig.raster.buffer.WriterBufferServer;
53
import org.gvsig.raster.dataset.GeoRasterWriter;
54
import org.gvsig.raster.dataset.IBuffer;
55
import org.gvsig.raster.dataset.IRasterDataSource;
56
import org.gvsig.raster.dataset.InvalidSetViewException;
57
import org.gvsig.raster.dataset.NotSupportedExtensionException;
58
import org.gvsig.raster.dataset.io.RasterDriverException;
59
import org.gvsig.raster.grid.Grid;
60
import org.gvsig.raster.grid.GridExtent;
61
import org.gvsig.raster.grid.OutOfGridException;
62
import org.gvsig.raster.util.RasterToolsUtil;
63

    
64
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
65
import com.iver.andami.PluginServices;
66
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
67
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
68
import com.iver.cit.gvsig.fmap.MapContext;
69
import com.iver.cit.gvsig.fmap.layers.FLayer;
70
import com.iver.cit.gvsig.fmap.layers.FLayers;
71

    
72
/** 
73
* Clase que implementa el proceso de construccion de un mosaico.
74
* 
75
* @author aMu?oz (alejandro.mu?oz@uclm.es)
76
* @version 30/4/2008
77
* */
78

    
79
public class MosaicProcess extends RasterProcess {
80

    
81
        // Layers que intervienen en el proceso
82
        private FLayers layers = null;
83

    
84
        // Extend completo del mosaico
85
        private GridExtent fullExtend= null;
86
        
87
        // Grid resultante
88
        Grid mosaicGrid = null;
89
        
90
        // Buffers con las imagenes
91
        RasterBuffer buffers[]= null;
92
        
93
        // Codigo operacion mayor, menor,media valor de la situada encima.
94
        int codOp= 0; 
95
        
96
        // indicador de proceso
97
        int percent=0;
98
         
99
//         PROVISIONAL -para cargar capa en vista-
100
        private MapContext mapContext                         = null;
101
         
102
        // writer para escritura en fichero 
103
        private WriterBufferServer writerBufferServer =null;
104
        
105
//  Numero de bandas 3 o 1 dependiendo de si es RGB o Nivel de gris
106
        int numbands=0;
107
         
108
         
109
        
110
        /** Inicializaci?n de los par?metros
111
         *  layers -  FLayers con los layers seleccionados para el mosaico.
112
         * 
113
         *         En la inicializacion se calcula el grid resultante.
114
         * */
115
        public void init() {
116
                
117
                layers= (FLayers)getParam("layers");
118
                codOp= getIntParam("codOp");
119
                numbands= getIntParam("numbands");
120
//                 PROVISIONAL
121
                mapContext = (MapContext)getParam("contexto");        
122
//                 Calculo del extend resultante
123
                fullExtend= calculateExtend(layers);
124
                
125
                int bands[]= new int[numbands];
126
                for(int i=0; i<numbands;i++)
127
                        bands[i]=i;
128
                try {
129
                                mosaicGrid= new Grid(fullExtend,fullExtend,IBuffer.TYPE_BYTE,bands);
130
                } catch (RasterBufferInvalidException e) {
131
                        RasterToolsUtil.messageBoxError("buffer_incorrecto", this, e);
132
                }
133
        }
134

    
135
        
136
        /**
137
         *  Proceso
138
         * */
139
        public void process() throws InterruptedException {
140
                
141
                // Parte de carga de los datos
142
                buffers= new RasterBuffer[layers.getLayersCount()];
143
                IRasterDataSource dsetCopy = null; 
144
                try {
145
                
146
                        double minX= fullExtend.getMin().getX();
147
                        double minY= fullExtend.getMin().getY();
148
                        double maxX=  fullExtend.getMax().getX();
149
                        double maxY=  fullExtend.getMax().getY();
150
                        // Se cargan todos los raster en los grid correspondientes
151
                        percent=0;
152
                        for(int i=0; i< layers.getLayersCount();i++)
153
                        {
154
                                dsetCopy = ((FLyrRasterSE)layers.getLayer(i)).getDataSource().newDataset();
155
                                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
156
                                bufferFactory.setAdjustToExtent(false);
157
                                if (!RasterBuffer.loadInMemory(dsetCopy))
158
                                        bufferFactory.setReadOnly(true);
159
                                bufferFactory.setDrawableBands(((FLyrRasterSE)layers.getLayer(i)).getRenderBands());
160
                                bufferFactory.setAreaOfInterest(minX,minY,maxX,maxY,fullExtend.getNX(),fullExtend.getNY());
161
                                buffers[i]= (RasterBuffer) bufferFactory.getRasterBuf();
162
                                percent=(int)(i*100/layers.getLayersCount());
163
                        }
164
                }catch (RasterDriverException e) {
165
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);        
166
                } catch (InvalidSetViewException e) {
167
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_extension"), this, e);        
168
                } catch (InterruptedException e) {
169
                        Thread.currentThread().interrupt();
170
                }
171
                
172
            
173
//                 Construccion del mosaico: Operaci?n M?ximo
174
                if(codOp==0){
175
                        int progress = 0;
176
                        for(int band=0; band<numbands; band++){
177
                                mosaicGrid.setBandToOperate(band);
178
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
179
                                        progress++;
180
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
181
                                                setValueMax(row,col,band);
182
                                        }
183
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
184
                                }
185
                        }
186
                }
187
                
188
//                Construccion del mosaico: Operaci?n M?nimo
189
                if(codOp==1){
190
                        int progress = 0;
191
                        for(int band=0; band<numbands; band++){
192
                                mosaicGrid.setBandToOperate(band);
193
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
194
                                        progress++;
195
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
196
                                                setValueMin(row,col,band);
197
                                        }
198
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
199
                                }
200
                        }
201
                }
202
                
203
//                 Construccion del mosaico: Operaci?n Media
204
                if(codOp==2){
205
                        int progress = 0;
206
                        for(int band=0; band<numbands; band++){
207
                                mosaicGrid.setBandToOperate(band);
208
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
209
                                        progress++;
210
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
211
                                                setValueMean(row,col,band);
212
                                        }
213
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
214
                                }
215
                        }
216
                }
217
                
218
//                Construccion del mosaico: Operacion valor de capa de delantera
219
                if(codOp==3){
220
                        int progress = 0;
221
                        for(int band=0; band<numbands; band++){
222
                                mosaicGrid.setBandToOperate(band);
223
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
224
                                        progress++;
225
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
226
                                                setValueFront(row,col,band);
227
                                        }
228
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
229
                                }
230
                        }
231
                }
232
                
233
                
234
                
235
//                Construccion del mosaico: Operaci?n Valor de capa de trasera
236
                if(codOp==4){
237
                        
238
                        // Cambio de orden del los elementos del buffer las capas inferiores pasan al principio del array
239
                        RasterBuffer buffersCopy[]= new RasterBuffer[buffers.length];
240
                        for(int i=0; i<buffers.length;i++)
241
                                buffersCopy[i]=buffers[i];
242
                        int k=buffers.length-1;
243
                        for(int i=0; i<buffers.length;i++){
244
                                buffers[i]=buffersCopy[k];
245
                                k--;
246
                        }
247
                        int progress = 0;
248
                        for(int band=0; band<numbands; band++){
249
                                mosaicGrid.setBandToOperate(band);
250
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
251
                                        progress++;
252
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
253
                                                setValueBack(row,col,band);
254
                                        }
255
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
256
                                }
257
                        }
258
                }
259
                
260
                // Escritura en fichero
261
                writeToFile((RasterBuffer)mosaicGrid.getRasterBuf(),0);
262
        //        writeToFile((RasterBuffer)buffers[0],1);
263
        //        writeToFile((RasterBuffer)buffers[1],2);
264
        }
265

    
266
        
267
        /**
268
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
269
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
270
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
271
         *  @param cordenada x 
272
         *  @param coordenada y  
273
         * */
274
        public void setValueMax(int x, int y, int band){
275
                byte result=-128;
276
                for(int buf=0;buf<buffers.length;buf++){
277
                        byte data = (byte)(buffers[buf].getElemByte(y,x,band));
278
//                                 TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
279
                        if(data==97)
280
                                data=-128;
281
                        result=(byte) Math.max((byte)result,(byte)data);                
282
                }
283
                try {
284
                                mosaicGrid.setCellValue(x,y,(byte)result);
285
                                result=-128;
286
                } catch (OutOfGridException e) {
287
                                e.printStackTrace();
288
                }
289
        }
290
        
291
        /**
292
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
293
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
294
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
295
         *  @param cordenada x 
296
         *  @param coordenada y  
297
         * */
298
        public void setValueMin(int x, int y,int band){
299
                byte result=127;
300
                        for(int buf=0;buf<buffers.length;buf++){
301
                                byte data = (byte)(buffers[buf].getElemByte(y,x,band)&0xff);
302
                                // TO DO: TENER EN CUENTA NO DATA
303
                                if(data==97)
304
                                        data=127;
305
                                result=(byte) Math.min((byte)result,(byte)data);                
306
                        }
307
                        try {
308
                                mosaicGrid.setCellValue(x,y,(byte)result);
309
                        } catch (OutOfGridException e) {
310
                                // TODO Auto-generated catch block
311
                                e.printStackTrace();
312
                        }
313
        }
314
        
315
        
316
        /**
317
         *  M?todo que establece para la coordenada x,y el valor medio  
318
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
319
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
320
         *  @param cordenada x 
321
         *  @param coordenada y  
322
         * */
323
        public void setValueMean(int x, int y, int band){
324
                int result=0;
325
                int buffTotales= buffers.length;
326
                for(int buf=0;buf<buffers.length;buf++){
327
                        int data = (int)((byte)(buffers[buf].getElemByte(y,x,band)));
328
//                        TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
329
                        if(data==97){
330
                                buffTotales--;
331
                                data =0;
332
                        }
333
                        result+=data;                
334
                }
335
                if(buffTotales==0)
336
                        buffTotales=1;
337
                result=(byte)((result/buffTotales));
338
                try {
339
                                mosaicGrid.setCellValue(x,y,(byte)(result));
340
                } catch (OutOfGridException e) {
341
                                e.printStackTrace();
342
                }
343
        }
344
        
345
        
346
        /**
347
         *  M?todo que establece para la coordenada x,y el valor de la capa superior 
348
         *  en caso de solape. Se parte de un array de buffer ordenados, de tal manera que
349
         *  el primer elemento corresponde a la capa situada mas al frente. El ?ltimo por 
350
         *  contra es el situado al fondo.
351
         
352
         *  @param cordenada x 
353
         *  @param coordenada y  
354
         * */
355
        public void setValueFront(int x, int y, int band){
356
                byte result=0;
357
                for(int buf=0;buf<buffers.length;buf++){
358
                        result = (byte)(buffers[buf].getElemByte(y,x,band));
359
                        // TO DO : Valor no data del buffer
360
                        if(result!=97)
361
                                        break;
362
                }
363
                
364
                try {
365
                                mosaicGrid.setCellValue(x,y,(byte)result);
366
                } catch (OutOfGridException e) {
367
                                e.printStackTrace();
368
                }
369
        }
370
        
371
        
372
        
373
        
374
        /**
375
         *  M?todo que establece para la coordenada x,y el valor de la capa inferior
376
         *  en caso de solape. Se parte de un array de buffer ordenados, de tal manera que
377
         *  el primer elemento corresponde a la capa situada mas al frente. El ?ltimo por 
378
         *  contra es el situado al fondo.
379
         
380
         *  @param cordenada x 
381
         *  @param coordenada y  
382
         * */
383
        public void setValueBack(int x, int y, int band){
384
                byte result=0;
385
                for(int buf=0;buf<buffers.length;buf++){
386
                        result = (byte)(buffers[buf].getElemByte(y,x,band));
387
                        // TO DO : Valor no data del buffer
388
                        if(result!=97)
389
                                        break;
390
                }
391
                
392
                try {
393
                                mosaicGrid.setCellValue(x,y,(byte)result);
394
                } catch (OutOfGridException e) {
395
                                e.printStackTrace();
396
                }
397
        }
398
        
399
        
400
        
401
        /**
402
         * M?todo que calcula el extend resultante para la operaci?n de mosaico
403
         * 
404
         * @param layers que intervienen en la operacion.
405
         * @return GridExtend del mosaico
406
         * */
407
        
408
        private GridExtent calculateExtend (FLayers layers){
409
                GridExtent result= null;
410
                
411
                double minX=0,maxX=0,minY=0,maxY=0, cellSize=25;
412
                try {
413
                        
414
                        minX = layers.getLayer(0).getFullExtent().getMinX();
415
                        minY = layers.getLayer(0).getFullExtent().getMinY();
416
                        maxX = layers.getLayer(0).getFullExtent().getMaxX();
417
                        maxY = layers.getLayer(0).getFullExtent().getMaxY();
418
                        
419
                        for(int i=1; i<layers.getLayersCount();i++){
420
                                minX= Math.min(minX,layers.getLayer(i).getFullExtent().getMinX());
421
                                minY= Math.min(minY,layers.getLayer(i).getFullExtent().getMinY());
422
                                maxX= Math.max(maxX,layers.getLayer(i).getFullExtent().getMaxX());
423
                                maxY= Math.max(maxY,layers.getLayer(i).getFullExtent().getMaxY());
424
                        }
425
                        
426
                } catch (ExpansionFileReadException e) {
427
                        e.printStackTrace();
428
                } catch (ReadDriverException e) {
429
                        e.printStackTrace();
430
                }
431
                
432
                result = new GridExtent(minX,minY,maxX,maxY,cellSize);
433
                return result;
434
        }
435
        
436
        /**
437
         *  M?todo que escribe en fichero el grid resultante de la operaci?n de mosaico.
438
         *  
439
         * */
440
        public void writeToFile(RasterBuffer buf, int i){
441
                try{
442
                        
443
                        String filename= "mosaico"+i+".tif";
444
                        GeoRasterWriter grw = null;
445
                        writerBufferServer = new WriterBufferServer(buf);
446
                        AffineTransform aTransform = new AffineTransform(fullExtend.getCellSize(),0.0,0.0,-fullExtend.getCellSize(),fullExtend.getMin().getX(),fullExtend.getMax().getY());
447
                        grw = GeoRasterWriter.getWriter(writerBufferServer, filename, mosaicGrid.getBandCount(),aTransform, mosaicGrid.getRasterBuf().getWidth(), mosaicGrid.getRasterBuf().getHeight(), mosaicGrid.getRasterBuf().getDataType(), GeoRasterWriter.getWriter(filename).getParams(), null);
448
                        grw.dataWrite();
449
                        grw.setWkt((String)((FLyrRasterSE)layers.getLayer(0)).getWktProjection());
450
                        grw.writeClose();
451
                        
452
                        //mapContext.beginAtomicEvent();
453
                        FLayer lyr = null;
454
                        int endIndex = filename.lastIndexOf(".");
455
                        if (endIndex < 0)
456
                                endIndex = filename.length();
457
                
458
                        lyr = FLyrRasterSE.createLayer(
459
                                        filename.substring(filename.lastIndexOf(File.separator) + 1, endIndex),
460
                                        filename,
461
                                        ((FLyrRasterSE)layers.getLayer(0)).getProjection()
462
                                        );
463

    
464
                        mapContext.getLayers().addLayer(lyr);
465
                        mapContext.endAtomicEvent();
466
                        mapContext.invalidate();
467
                
468
                } catch (NotSupportedExtensionException e) {
469
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer_notsupportedextension"), this, e);
470
                } catch (RasterDriverException e) {
471
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);        
472
                } catch (IOException e) {
473
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);
474
                }catch (LoadLayerException e) {
475
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
476
                }catch (InterruptedException e) {
477
                        Thread.currentThread().interrupt();
478
                }         
479
        }
480
        
481
        
482
        /**
483
         * @return descripcion
484
         * */
485
        public String getTitle() {
486
                return PluginServices.getText(this,"mosaic_process");
487
        }
488

    
489
        
490
        /**
491
         * @return  indicador de progreso
492
         * */
493
        public int getPercent() {
494
                if(writerBufferServer==null)
495
                        return percent;
496
                else 
497
                        return writerBufferServer.getPercent();
498
        }
499

    
500

    
501
        /*
502
        // Identificaci?n de zonas de solapamiento
503
        public boolean getSolapes(FLyrRasterSE raster1, FLyrRasterSE raster2){
504
                
505
                Grid grid1=null, grid2=null, aux=null;;
506
                IRasterDataSource dsetCopy = null; 
507
                dsetCopy =raster1.getDataSource().newDataset();
508
                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
509
                
510
                IRasterDataSource dsetCopy2 = null; 
511
                dsetCopy2 =raster2.getDataSource().newDataset();
512
                BufferFactory bufferFactory2 = new BufferFactory(dsetCopy2);
513
                
514
                
515
                if (!RasterBuffer.loadInMemory(dsetCopy))
516
                        bufferFactory.setReadOnly(true);        
517
                
518
                try {
519
                        grid1 = new Grid(bufferFactory,raster1.getRenderBands());
520
                        grid2= new Grid(bufferFactory2,raster2.getRenderBands());
521
                } catch (RasterBufferInvalidException e) {
522
                        e.printStackTrace();
523
                }        
524
                
525
                // En grid1 la imagen con la cordenada x menor.
526
                if(grid2.getGridExtent().getMin().getX()< grid1.getGridExtent().getMin().getX())
527
                        {
528
                                try {
529
                                        grid1 = new Grid(bufferFactory2,raster2.getRenderBands());
530
                                        grid2= new Grid(bufferFactory,raster1.getRenderBands());
531
                                } catch (RasterBufferInvalidException e) {
532
                                        e.printStackTrace();
533
                                }        
534
                                
535
                        }
536
                
537
                double xmin= grid1.getGridExtent().getMin().getX();
538
                double xmax= grid1.getGridExtent().getMax().getX();
539
                double ymin= grid1.getGridExtent().getMin().getY();
540
                double ymax= grid1.getGridExtent().getMax().getY();
541
                
542
                double xmin2= grid2.getGridExtent().getMin().getX();
543
                double ymin2= grid2.getGridExtent().getMin().getY();
544
                
545
                if(!(xmin2>xmin && xmin2<xmax)){
546
                        System.out.print("Las imagenes no se solapan en las X");
547
                        return false;
548
                }
549
        
550
                if(!(ymin2>ymin && ymin2<ymax)){
551
                        System.out.print("Las imagenes no se solapan en las Y");
552
                        return false;
553
                }
554
                
555
                // Detectado el solapamiento
556
                System.out.print("Rango x["+ xmin2 + ","+ Math.min(xmax,grid2.getGridExtent().getMax().getX())+"].");
557
                System.out.print("Rango y["+ ymin2 + ","+ Math.min(ymax,grid2.getGridExtent().getMax().getY())+"].");
558
                
559
                return true;
560
        }*/
561

    
562

    
563
}