Statistics
| Revision:

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

History | View | Annotate | Download (14.6 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: Operaci?n Superior
219
                if(codOp==3){
220
                        for(int col=0; col<mosaicGrid.getLayerNY(); col++){
221
                                for(int row=0; row<mosaicGrid.getLayerNX();row++){
222
                                        //setValueMax(row,col);
223
                                        percent= col*100/mosaicGrid.getLayerNY();
224
                                }
225
                        }
226
                }
227
                
228
                // Escritura en fichero
229
                writeToFile((RasterBuffer)mosaicGrid.getRasterBuf(),0);
230
                writeToFile((RasterBuffer)buffers[0],1);
231
                writeToFile((RasterBuffer)buffers[1],2);
232
        }
233

    
234
        
235
        /**
236
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
237
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
238
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
239
         *  @param cordenada x 
240
         *  @param coordenada y  
241
         * */
242
        public void setValueMax(int x, int y, int band){
243
                byte result=-128;
244
                for(int buf=0;buf<buffers.length;buf++){
245
                        byte data = (byte)(buffers[buf].getElemByte(y,x,band));
246
//                                 TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
247
                        if(data==97)
248
                                data=-128;
249
                        result=(byte) Math.max((byte)result,(byte)data);                
250
                }
251
                try {
252
                                mosaicGrid.setCellValue(x,y,(byte)result);
253
                                result=-128;
254
                } catch (OutOfGridException e) {
255
                                e.printStackTrace();
256
                }
257
        }
258
        
259
        /**
260
         *  M?todo que establece para la coordenada x,y el valor m?ximo 
261
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
262
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
263
         *  @param cordenada x 
264
         *  @param coordenada y  
265
         * */
266
        public void setValueMin(int x, int y,int band){
267
                byte result=127;
268
                        for(int buf=0;buf<buffers.length;buf++){
269
                                byte data = (byte)(buffers[buf].getElemByte(y,x,band)&0xff);
270
                                // TO DO: TENER EN CUENTA NO DATA
271
                                if(data==97)
272
                                        data=127;
273
                                result=(byte) Math.min((byte)result,(byte)data);                
274
                        }
275
                        try {
276
                                mosaicGrid.setCellValue(x,y,(byte)result);
277
                        } catch (OutOfGridException e) {
278
                                // TODO Auto-generated catch block
279
                                e.printStackTrace();
280
                        }
281
        }
282
        
283
        
284
        /**
285
         *  M?todo que establece para la coordenada x,y el valor medio  
286
         *  de todos los valores para ese p?xel en cualquiera de las imagenes.
287
         *  Si el valor en cualquiera de las imagenes es noData no es tenido en cuenta 
288
         *  @param cordenada x 
289
         *  @param coordenada y  
290
         * */
291
        public void setValueMean(int x, int y, int band){
292
                int result=0;
293
                int buffTotales= buffers.length;
294
                for(int buf=0;buf<buffers.length;buf++){
295
                        int data = (int)((byte)(buffers[buf].getElemByte(y,x,band)&0xff)+127);
296
//                        TO DO: TENER EN CUENTA NODATA REAL DEL BUFER
297
                        if(data==97+127){
298
                                buffTotales--;
299
                                data =0;
300
                        }
301
                        result+=data;                
302
                }
303
                if(buffTotales==0)
304
                        buffTotales=1;
305
                result=(int)((result/buffTotales));
306
                try {
307
                                mosaicGrid.setCellValue(x,y,(byte)(result-127));
308
                } catch (OutOfGridException e) {
309
                                e.printStackTrace();
310
                }
311
        }
312
        
313
        
314

    
315
        /**
316
         * M?todo que calcula el extend resultante para la operaci?n de mosaico
317
         * 
318
         * @param layers que intervienen en la operacion.
319
         * @return GridExtend del mosaico
320
         * */
321
        
322
        private GridExtent calculateExtend (FLayers layers){
323
                GridExtent result= null;
324
                
325
                double minX=0,maxX=0,minY=0,maxY=0, cellSize=25;
326
                try {
327
                        
328
                        minX = layers.getLayer(0).getFullExtent().getMinX();
329
                        minY = layers.getLayer(0).getFullExtent().getMinY();
330
                        maxX = layers.getLayer(0).getFullExtent().getMaxX();
331
                        maxY = layers.getLayer(0).getFullExtent().getMaxY();
332
                        
333
                        for(int i=1; i<layers.getLayersCount();i++){
334
                                minX= Math.min(minX,layers.getLayer(i).getFullExtent().getMinX());
335
                                minY= Math.min(minY,layers.getLayer(i).getFullExtent().getMinY());
336
                                maxX= Math.max(maxX,layers.getLayer(i).getFullExtent().getMaxX());
337
                                maxY= Math.max(maxY,layers.getLayer(i).getFullExtent().getMaxY());
338
                        }
339
                        
340
                } catch (ExpansionFileReadException e) {
341
                        e.printStackTrace();
342
                } catch (ReadDriverException e) {
343
                        e.printStackTrace();
344
                }
345
                
346
                result = new GridExtent(minX,minY,maxX,maxY,cellSize);
347
                return result;
348
        }
349
        
350
        /**
351
         *  M?todo que escribe en fichero el grid resultante de la operaci?n de mosaico.
352
         *  
353
         * */
354
        public void writeToFile(RasterBuffer buf, int i){
355
                try{
356
                        
357
                        String filename= "mosaico"+i+".tif";
358
                        GeoRasterWriter grw = null;
359
                        writerBufferServer = new WriterBufferServer(buf);
360
                        AffineTransform aTransform = new AffineTransform(fullExtend.getCellSize(),0.0,0.0,-fullExtend.getCellSize(),fullExtend.getMin().getX(),fullExtend.getMax().getY());
361
                        grw = GeoRasterWriter.getWriter(writerBufferServer, filename, mosaicGrid.getBandCount(),aTransform, mosaicGrid.getRasterBuf().getWidth(), mosaicGrid.getRasterBuf().getHeight(), mosaicGrid.getRasterBuf().getDataType(), GeoRasterWriter.getWriter(filename).getParams(), null);
362
                        grw.dataWrite();
363
                        grw.setWkt((String)((FLyrRasterSE)layers.getLayer(0)).getWktProjection());
364
                        grw.writeClose();
365
                        
366
                        //mapContext.beginAtomicEvent();
367
                        FLayer lyr = null;
368
                        int endIndex = filename.lastIndexOf(".");
369
                        if (endIndex < 0)
370
                                endIndex = filename.length();
371
                
372
                        lyr = FLyrRasterSE.createLayer(
373
                                        filename.substring(filename.lastIndexOf(File.separator) + 1, endIndex),
374
                                        filename,
375
                                        ((FLyrRasterSE)layers.getLayer(0)).getProjection()
376
                                        );
377

    
378
                        mapContext.getLayers().addLayer(lyr);
379
                        mapContext.endAtomicEvent();
380
                        mapContext.invalidate();
381
                
382
                } catch (NotSupportedExtensionException e) {
383
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer_notsupportedextension"), this, e);
384
                } catch (RasterDriverException e) {
385
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);        
386
                } catch (IOException e) {
387
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);
388
                }catch (LoadLayerException e) {
389
                        RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
390
                }catch (InterruptedException e) {
391
                        Thread.currentThread().interrupt();
392
                }         
393
        }
394
        
395
        
396
        /**
397
         * @return descripcion
398
         * */
399
        public String getTitle() {
400
                return PluginServices.getText(this,"mosaic_process");
401
        }
402

    
403
        
404
        /**
405
         * @return  indicador de progreso
406
         * */
407
        public int getPercent() {
408
                if(writerBufferServer==null)
409
                        return percent;
410
                else 
411
                        return writerBufferServer.getPercent();
412
        }
413

    
414

    
415
        /*
416
        // Identificaci?n de zonas de solapamiento
417
        public boolean getSolapes(FLyrRasterSE raster1, FLyrRasterSE raster2){
418
                
419
                Grid grid1=null, grid2=null, aux=null;;
420
                IRasterDataSource dsetCopy = null; 
421
                dsetCopy =raster1.getDataSource().newDataset();
422
                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
423
                
424
                IRasterDataSource dsetCopy2 = null; 
425
                dsetCopy2 =raster2.getDataSource().newDataset();
426
                BufferFactory bufferFactory2 = new BufferFactory(dsetCopy2);
427
                
428
                
429
                if (!RasterBuffer.loadInMemory(dsetCopy))
430
                        bufferFactory.setReadOnly(true);        
431
                
432
                try {
433
                        grid1 = new Grid(bufferFactory,raster1.getRenderBands());
434
                        grid2= new Grid(bufferFactory2,raster2.getRenderBands());
435
                } catch (RasterBufferInvalidException e) {
436
                        e.printStackTrace();
437
                }        
438
                
439
                // En grid1 la imagen con la cordenada x menor.
440
                if(grid2.getGridExtent().getMin().getX()< grid1.getGridExtent().getMin().getX())
441
                        {
442
                                try {
443
                                        grid1 = new Grid(bufferFactory2,raster2.getRenderBands());
444
                                        grid2= new Grid(bufferFactory,raster1.getRenderBands());
445
                                } catch (RasterBufferInvalidException e) {
446
                                        e.printStackTrace();
447
                                }        
448
                                
449
                        }
450
                
451
                double xmin= grid1.getGridExtent().getMin().getX();
452
                double xmax= grid1.getGridExtent().getMax().getX();
453
                double ymin= grid1.getGridExtent().getMin().getY();
454
                double ymax= grid1.getGridExtent().getMax().getY();
455
                
456
                double xmin2= grid2.getGridExtent().getMin().getX();
457
                double ymin2= grid2.getGridExtent().getMin().getY();
458
                
459
                if(!(xmin2>xmin && xmin2<xmax)){
460
                        System.out.print("Las imagenes no se solapan en las X");
461
                        return false;
462
                }
463
        
464
                if(!(ymin2>ymin && ymin2<ymax)){
465
                        System.out.print("Las imagenes no se solapan en las Y");
466
                        return false;
467
                }
468
                
469
                // Detectado el solapamiento
470
                System.out.print("Rango x["+ xmin2 + ","+ Math.min(xmax,grid2.getGridExtent().getMax().getX())+"].");
471
                System.out.print("Rango y["+ ymin2 + ","+ Math.min(ymax,grid2.getGridExtent().getMax().getY())+"].");
472
                
473
                return true;
474
        }*/
475

    
476

    
477
}