Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / mosaic / process / MosaicProcess.java @ 22548

History | View | Annotate | Download (17.8 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.IOException;
45

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

    
63
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
64
import com.iver.andami.PluginServices;
65
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
66
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
67
import com.iver.cit.gvsig.fmap.layers.FLayers;
68
import com.iver.cit.gvsig.project.documents.view.gui.View;
69

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

    
77
public class MosaicProcess extends RasterProcess {
78

    
79
        // Layers que intervienen en el proceso
80
        private FLyrRasterSE inputRasterLayers[] = null;
81
        
82
        //Layer de salida
83
        private FLyrRasterSE outputRasterLayer = null;
84

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

    
140
        
141
        /**
142
         *  Proceso
143
         * */
144
        public void process() throws InterruptedException {
145
                
146
                // Parte de carga de los datos
147
                buffers= new RasterBuffer[inputRasterLayers.length];
148
                IRasterDataSource dsetCopy = null; 
149
                try {
150
                
151
                        double minX= fullExtend.getMin().getX();
152
                        double minY= fullExtend.getMin().getY();
153
                        double maxX=  fullExtend.getMax().getX();
154
                        double maxY=  fullExtend.getMax().getY();
155
                        // Se cargan todos los raster en los grid correspondientes
156
                        percent=1;
157
                        for(int i=0; i< inputRasterLayers.length;i++)
158
                        {        
159
                                dsetCopy = ((FLyrRasterSE)inputRasterLayers[i]).getDataSource().newDataset();
160
                                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
161
                                bufferFactory.setAdjustToExtent(false);
162
                                if (!RasterBuffer.loadInMemory(dsetCopy))
163
                                        bufferFactory.setReadOnly(true);
164
                                // Si pongo solo las renderizadas en algunos casos da problemas
165
                                bufferFactory.setAllDrawableBands();
166
                                bufferFactory.setAreaOfInterest(minX,minY,maxX,maxY,fullExtend.getNX(),fullExtend.getNY());
167
                                buffers[i]= (RasterBuffer) bufferFactory.getRasterBuf();
168
                                percent=(int)((i+1)*100/inputRasterLayers.length);
169

    
170
                        
171
                        }
172
                }catch (RasterDriverException e) {
173
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);        
174
                } catch (InvalidSetViewException e) {
175
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_extension"), this, e);        
176
                } catch (InterruptedException e) {
177
                        Thread.currentThread().interrupt();
178
                }
179
                
180
                proceso=1;
181
            
182
//                 Construccion del mosaico: Operaci?n M?ximo
183
                if(codOp==0){
184
                        int progress = 0;
185
                        for(int band=0; band<numbands; band++){
186
                                mosaicGrid.setBandToOperate(band);
187
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
188
                                        progress++;
189
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
190
                                                setValueMax(row,col,band);
191
                                        }
192
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
193
                                }
194
                        }
195
                }
196
                
197
//                Construccion del mosaico: Operaci?n M?nimo
198
                if(codOp==1){
199
                        int progress = 0;
200
                        for(int band=0; band<numbands; band++){
201
                                mosaicGrid.setBandToOperate(band);
202
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
203
                                        progress++;
204
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
205
                                                setValueMin(row,col,band);
206
                                        }
207
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
208
                                }
209
                        }
210
                }
211
                
212
//                 Construccion del mosaico: Operaci?n Media
213
                if(codOp==2){
214
                        int progress = 0;
215
                        for(int band=0; band<numbands; band++){
216
                                mosaicGrid.setBandToOperate(band);
217
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
218
                                        progress++;
219
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
220
                                                setValueMean(row,col,band);
221
                                        }
222
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
223
                                }
224
                        }
225
                }
226
                
227
//                Construccion del mosaico: Operacion valor de capa de delantera
228
                if(codOp==3){
229
                        int progress = 0;
230
                        for(int band=0; band<numbands; band++){
231
                                mosaicGrid.setBandToOperate(band);
232
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
233
                                        progress++;
234
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
235
                                                setValueFront(row,col,band);
236
                                        }
237
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
238
                                }
239
                        }
240
                }
241
                
242
                
243
//                Construccion del mosaico: Operaci?n Valor de capa de trasera
244
                if(codOp==4){
245
                        
246
                        // Cambio de orden del los elementos del buffer las capas inferiores pasan al principio del array
247
                        RasterBuffer buffersCopy[]= new RasterBuffer[buffers.length];
248
                        for(int i=0; i<buffers.length;i++)
249
                                buffersCopy[i]=buffers[i];
250
                        int k=buffers.length-1;
251
                        for(int i=0; i<buffers.length;i++){
252
                                buffers[i]=buffersCopy[k];
253
                                k--;
254
                        }
255
                        int progress = 0;
256
                        for(int band=0; band<numbands; band++){
257
                                mosaicGrid.setBandToOperate(band);
258
                                for(int col=0; col<mosaicGrid.getLayerNY(); col++){
259
                                        progress++;
260
                                        for(int row=0; row<mosaicGrid.getLayerNX();row++){
261
                                                setValueBack(row,col,band);
262
                                        }
263
                                        percent=(int)( progress*100/(mosaicGrid.getLayerNY()*numbands));
264
                                }
265
                        }
266
                }
267
                
268
                // Se liberan los buffers
269
                for(int i=0; i<inputRasterLayers.length;i++)
270
                        buffers[i].free();
271
                
272
                // Escritura en fichero
273
                proceso=2;
274
                createLayer();
275
                if (externalActions != null)
276
                        externalActions.end(outputRasterLayer);
277
        }
278

    
279
        
280
        /**
281
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
282
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
283
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
284
         *  @param cordenada x 
285
         *  @param coordenada y  
286
         * */
287
        public void setValueMax(int x, int y, int band){
288
                byte result=-128;
289
                for(int buf=0;buf<buffers.length;buf++){
290
                        byte data = (byte)(buffers[buf].getElemByte(y,x,band)&0xff);
291
//                                 TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
292
                        if(data==(byte)mosaicGrid.getNoDataValue())
293
                                data=-128;
294
                        result=(byte) Math.max((byte)result,(byte)data);                
295
                }
296
                try {
297
                                mosaicGrid.setCellValue(x,y,(byte)result);
298
                } catch (OutOfGridException e) {
299
                                e.printStackTrace();
300
                }
301
        }
302
        
303
        /**
304
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
305
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
306
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
307
         *  @param cordenada x 
308
         *  @param coordenada y  
309
         * */
310
        public void setValueMin(int x, int y,int band){
311
                byte result=127;
312
                        for(int buf=0;buf<buffers.length;buf++){
313
                                byte data = (byte)(buffers[buf].getElemByte(y,x,band)&0xff);
314
                                // TO DO: TENER EN CUENTA NO DATA
315
                                if(data==(byte)mosaicGrid.getNoDataValue())
316
                                        data=127;
317
                                result=(byte) Math.min((byte)result,(byte)data);                
318
                        }
319
                        try {
320
                                mosaicGrid.setCellValue(x,y,(byte)result);
321
                        } catch (OutOfGridException e) {
322
                                // TODO Auto-generated catch block
323
                                e.printStackTrace();
324
                        }
325
        }
326
        
327
        
328
        /**
329
         *  M?todo que establece para la coordenada x,y el valor medio  
330
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
331
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
332
         *  @param cordenada x 
333
         *  @param coordenada y  
334
         * */
335
        public void setValueMean(int x, int y, int band){
336
                int result=0;
337
                int buffTotales= buffers.length;
338
                for(int buf=0;buf<buffers.length;buf++){
339
                        int data = (int)((byte)(buffers[buf].getElemByte(y,x,band)));
340
//                        TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
341
                        if(data==(byte)mosaicGrid.getNoDataValue()){
342
                                buffTotales--;
343
                                data =0;
344
                        }
345
                        result+=data;                
346
                }
347
                if(buffTotales==0)
348
                        buffTotales=1;
349
                result=(byte)((result/buffTotales));
350
                try {
351
                                mosaicGrid.setCellValue(x,y,(byte)(result));
352
                } catch (OutOfGridException e) {
353
                                e.printStackTrace();
354
                }
355
        }
356
        
357
        
358
        /**
359
         *  M?todo que establece para la coordenada x,y el valor de la capa superior 
360
         *  en caso de solape. Se parte de un array de buffer ordenados, de tal manera que
361
         *  el primer elemento corresponde a la capa situada mas al frente. El ?ltimo por 
362
         *  contra es el situado al fondo.
363
         
364
         *  @param cordenada x 
365
         *  @param coordenada y  
366
         * */
367
        public void setValueFront(int x, int y, int band){
368
                byte result=0;
369
                for(int buf=0;buf<buffers.length;buf++){
370
                        result = (byte)(buffers[buf].getElemByte(y,x,band));
371
                        // TO DO : Valor no data del buffer
372
                        if(result!=(byte)mosaicGrid.getNoDataValue())
373
                                        break;
374
                }
375
                
376
                try {
377
                                mosaicGrid.setCellValue(x,y,(byte)result);
378
                } catch (OutOfGridException e) {
379
                                e.printStackTrace();
380
                }
381
        }
382
        
383
        
384
        /**
385
         *  M?todo que establece para la coordenada x,y el valor de la capa inferior
386
         *  en caso de solape. Se parte de un array de buffer ordenados, de tal manera que
387
         *  el primer elemento corresponde a la capa situada mas al frente. El ?ltimo por 
388
         *  contra es el situado al fondo.
389
         
390
         *  @param cordenada x 
391
         *  @param coordenada y  
392
         * */
393
        public void setValueBack(int x, int y, int band){
394
                byte result=0;
395
                for(int buf=0;buf<buffers.length;buf++){
396
                        result = (byte)(buffers[buf].getElemByte(y,x,band));
397
                        // TO DO : Valor no data del buffer
398
                        if(result!=(byte)mosaicGrid.getNoDataValue())
399
                                        break;
400
                }
401
                
402
                try {
403
                                mosaicGrid.setCellValue(x,y,(byte)result);
404
                } catch (OutOfGridException e) {
405
                                e.printStackTrace();
406
                }
407
        }
408
        
409
        
410
        /**
411
         * M?todo que calcula el extend resultante para la operaci?n de mosaico
412
         * 
413
         * @param layers que intervienen en la operacion.
414
         * @return GridExtend del mosaico
415
         * */
416
        
417
        private GridExtent calculateExtend (FLyrRasterSE layers[]){
418
                
419
                GridExtent result= null;
420
                IRasterDataSource dsetCopy = null; 
421
                double cellSize=0;
422
                double minX=0,maxX=0,minY=0,maxY=0;
423
                // Se obtiene el tama?o de celda mayor
424
                for(int i=0; i< layers.length;i++)
425
                {        
426
                        dsetCopy = ((FLyrRasterSE)layers[i]).getDataSource().newDataset();
427
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
428
                        bufferFactory.setAdjustToExtent(false);
429
                        cellSize= Math.max(cellSize,bufferFactory.getDataSource().getCellSize());
430
                }
431
                
432
                minX = layers[0].getFullExtent().getMinX();
433
                minY = layers[0].getFullExtent().getMinY();
434
                maxX = layers[0].getFullExtent().getMaxX();
435
                maxY = layers[0].getFullExtent().getMaxY();
436
                
437
                for(int i=1; i<layers.length;i++){
438
                        
439
                        minX= Math.min(minX,layers[i].getFullExtent().getMinX());
440
                        minY= Math.min(minY,layers[i].getFullExtent().getMinY());
441
                        maxX= Math.max(maxX,layers[i].getFullExtent().getMaxX());
442
                        maxY= Math.max(maxY,layers[i].getFullExtent().getMaxY());
443
                }
444
                
445
                result = new GridExtent(minX,minY,maxX,maxY,cellSize);
446
                return result;
447
        }
448
        
449
        /**
450
         * Escritura del resultado en disco y carga en la vista 
451
         */
452
        public void createLayer(){
453
                try{
454
                        // Escritura de los datos a fichero temporal
455
                        int endIndex = fileName.lastIndexOf(".");
456
                        if (endIndex < 0)
457
                                 endIndex = fileName.length();
458
                        GeoRasterWriter grw = null;
459
                        writerBufferServer = new WriterBufferServer(mosaicGrid.getRasterBuf());
460
                        AffineTransform aTransform = new AffineTransform(fullExtend.getCellSize(),0.0,0.0,-fullExtend.getCellSize(),fullExtend.getMin().getX(),fullExtend.getMax().getY());
461
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileName, mosaicGrid.getBandCount(),aTransform, mosaicGrid.getRasterBuf().getWidth(), mosaicGrid.getRasterBuf().getHeight(), mosaicGrid.getRasterBuf().getDataType(), GeoRasterWriter.getWriter(fileName).getParams(), null);
462
                        grw.dataWrite();
463
                        grw.setWkt((String)((FLyrRasterSE)inputRasterLayers[0]).getWktProjection());
464
                        grw.writeClose();
465
                        mosaicGrid.getRasterBuf().free();
466
                        outputRasterLayer = FLyrRasterSE.createLayer("outputLayer",
467
                                        fileName, null);
468
                        
469
                        //Borrar sin preguntar:
470
                        //RasterToolsUtil.loadLayer(PluginServices.getMDIManager().getWindowInfo(view).getTitle(), fileName, null);
471
        
472
                } catch (NotSupportedExtensionException e) {
473
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer_notsupportedextension"), this, e);
474
                } catch (IOException e) {
475
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);
476
                } catch (InterruptedException e) {
477
                                Thread.currentThread().interrupt();
478
                } catch (RasterDriverException e) {
479
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "raster_buffer_invalid_extension"), this, e);
480
                } catch (LoadLayerException e) {
481
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
482
                }
483

    
484
        }
485
        
486
        public Object getResult() {
487
                return outputRasterLayer;
488
        }
489

    
490

    
491
        /**
492
         * @return descripcion
493
         * */
494
        public String getTitle() {
495
                return PluginServices.getText(this,"mosaic_process");
496
        }
497

    
498
        
499
        /**
500
         *  @return String con el log en cada parte del proceso
501
         * */
502
        public String getLog()
503
        {
504
                if(proceso==0)
505
                        return PluginServices.getText(this,"load_buffer_data");
506
                else if (proceso==1)
507
                        return PluginServices.getText(this,"generate_mosaic");
508
                else
509
                        return PluginServices.getText(this,"write_to_file");
510
        }
511
        
512
        /**
513
         * @return  indicador de progreso
514
         * */
515
        public int getPercent() {
516
                if(writerBufferServer==null)
517
                        return percent;
518
                else 
519
                        return writerBufferServer.getPercent();
520
        }
521

    
522

    
523
        /*
524
        // Identificaci?n de zonas de solapamiento
525
        public boolean getSolapes(FLyrRasterSE raster1, FLyrRasterSE raster2){
526
                
527
                Grid grid1=null, grid2=null, aux=null;;
528
                IRasterDataSource dsetCopy = null; 
529
                dsetCopy =raster1.getDataSource().newDataset();
530
                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
531
                
532
                IRasterDataSource dsetCopy2 = null; 
533
                dsetCopy2 =raster2.getDataSource().newDataset();
534
                BufferFactory bufferFactory2 = new BufferFactory(dsetCopy2);
535
                
536
                
537
                if (!RasterBuffer.loadInMemory(dsetCopy))
538
                        bufferFactory.setReadOnly(true);        
539
                
540
                try {
541
                        grid1 = new Grid(bufferFactory,raster1.getRenderBands());
542
                        grid2= new Grid(bufferFactory2,raster2.getRenderBands());
543
                } catch (RasterBufferInvalidException e) {
544
                        e.printStackTrace();
545
                }        
546
                
547
                // En grid1 la imagen con la cordenada x menor.
548
                if(grid2.getGridExtent().getMin().getX()< grid1.getGridExtent().getMin().getX())
549
                        {
550
                                try {
551
                                        grid1 = new Grid(bufferFactory2,raster2.getRenderBands());
552
                                        grid2= new Grid(bufferFactory,raster1.getRenderBands());
553
                                } catch (RasterBufferInvalidException e) {
554
                                        e.printStackTrace();
555
                                }        
556
                                
557
                        }
558
                
559
                double xmin= grid1.getGridExtent().getMin().getX();
560
                double xmax= grid1.getGridExtent().getMax().getX();
561
                double ymin= grid1.getGridExtent().getMin().getY();
562
                double ymax= grid1.getGridExtent().getMax().getY();
563
                
564
                double xmin2= grid2.getGridExtent().getMin().getX();
565
                double ymin2= grid2.getGridExtent().getMin().getY();
566
                
567
                if(!(xmin2>xmin && xmin2<xmax)){
568
                        System.out.print("Las imagenes no se solapan en las X");
569
                        return false;
570
                }
571
        
572
                if(!(ymin2>ymin && ymin2<ymax)){
573
                        System.out.print("Las imagenes no se solapan en las Y");
574
                        return false;
575
                }
576
                
577
                // Detectado el solapamiento
578
                System.out.print("Rango x["+ xmin2 + ","+ Math.min(xmax,grid2.getGridExtent().getMax().getX())+"].");
579
                System.out.print("Rango y["+ ymin2 + ","+ Math.min(ymax,grid2.getGridExtent().getMax().getY())+"].");
580
                
581
                return true;
582
        }*/
583

    
584

    
585
}