Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / rastertools / clipping / ClippingProcess.java @ 16195

History | View | Annotate | Download (14.1 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
*
3
* Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
*
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
*/
19
package org.gvsig.rastertools.clipping;
20

    
21
import java.awt.geom.AffineTransform;
22
import java.io.File;
23
import java.io.FileNotFoundException;
24
import java.io.IOException;
25

    
26
import org.apache.log4j.Logger;
27
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
28
import org.gvsig.gui.beans.incrementabletask.IncrementableEvent;
29
import org.gvsig.gui.beans.incrementabletask.IncrementableListener;
30
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
31
import org.gvsig.raster.buffer.BufferFactory;
32
import org.gvsig.raster.buffer.BufferInterpolation;
33
import org.gvsig.raster.buffer.RasterBuffer;
34
import org.gvsig.raster.dataset.GeoRasterWriter;
35
import org.gvsig.raster.dataset.IBuffer;
36
import org.gvsig.raster.dataset.IRasterDataSource;
37
import org.gvsig.raster.dataset.InvalidSetViewException;
38
import org.gvsig.raster.dataset.NotSupportedExtensionException;
39
import org.gvsig.raster.dataset.Params;
40
import org.gvsig.raster.dataset.RasterDataset;
41
import org.gvsig.raster.dataset.RasterDriverException;
42
import org.gvsig.raster.dataset.io.rmf.RmfBlocksManager;
43
import org.gvsig.raster.datastruct.ColorTable;
44
import org.gvsig.raster.datastruct.serializer.ColorTableRmfSerializer;
45
import org.gvsig.raster.grid.GridPalette;
46
import org.gvsig.raster.grid.filter.RasterFilterList;
47
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
48
import org.gvsig.raster.process.CancelEvent;
49
import org.gvsig.raster.process.RasterTask;
50
import org.gvsig.raster.process.RasterTaskQueue;
51
import org.gvsig.raster.util.RasterNotLoadException;
52
import org.gvsig.raster.util.RasterToolsUtil;
53
import org.gvsig.raster.util.RasterUtilities;
54
import org.gvsig.rastertools.IProcessActions;
55
import org.gvsig.rastertools.RasterModule;
56
/**
57
 * <code>ClippingProcess</code> es un proceso que usa un <code>Thread</code>
58
 * para calcular el recorte de una capa.
59
 *
60
 * @version 24/04/2007
61
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
62
 */
63
public class ClippingProcess implements IncrementableListener, Runnable {
64
        private String             fileName            = "";
65
        private IncrementableTask  incrementableTask   = null;
66
        private volatile Thread    blinker             = null;
67
        private WriterBufferServer writerBufferServer  = null;
68
        private FLyrRasterSE       rasterSE            = null;
69
        private AffineTransform    affineTransform     = new AffineTransform();
70
        private boolean            oneLayerPerBand     = false;
71
        private int[]              drawableBands       = { 0, 1, 2 };
72
        private int[]              dValues             = null;
73
        private GeoRasterWriter    grw                 = null;
74
        private int                interpolationMethod = BufferInterpolation.INTERPOLATION_Undefined;
75
        private boolean            loadedInToc         = true;
76
        private String             viewName            = "";
77
        private Params             params              = null;
78
        private RasterTask         rasterTask          = new RasterTask(this);
79
        private IProcessActions    externalActions     = null;
80

    
81
        /**
82
         * Variables de la resoluci?n de salida
83
         */
84
        private int                resolutionWidth     = 0;
85
        private int                resolutionHeight    = 0;
86

    
87
        /**
88
         * Crea un <code>ClippingProcess</code> para generar un recorte
89
         * @param dValues
90
         * @param fileName
91
         * @param writerBufferServer
92
         * @param rasterMultiDataset
93
         * @param extent
94
         * @param drawableBands
95
         * @param oneLayerPerBand
96
         */
97
        public ClippingProcess(String viewName, int[] dValues, String fileName,
98
                                                        WriterBufferServer writerBufferServer, FLyrRasterSE rasterSE) {
99
                this.fileName = fileName;
100
                this.writerBufferServer = writerBufferServer;
101
                this.rasterSE = rasterSE;
102
                this.dValues = dValues;
103
                this.viewName = viewName;
104
        }
105

    
106
        /**
107
         * Arranca el proceso de recorte de un layer
108
         */
109
        public void start() {
110
                blinker = new Thread(this);
111
                blinker.start();
112
        }
113

    
114
        /**
115
         * Establecer la resolucion de salida al crear el recorte
116
         * @param width
117
         * @param height
118
         */
119
        public void setResolution(int width, int height) {
120
                resolutionWidth = width;
121
                resolutionHeight = height;
122
        }
123

    
124
        /**
125
         * Salva la tabla de color al fichero rmf.
126
         * @param fName
127
         * @throws IOException
128
         */
129
        private void saveToRmf(String fileName) {
130
                fileName = RasterUtilities.getNameWithoutExtension(fileName) + ".rmf";
131
                
132
                RasterDataset rds = null;
133
                int limitNumberOfRequests = 20;
134
                while(rds == null && limitNumberOfRequests > 0) {
135
                        try {
136
                                rds = rasterSE.getDataSource().getDataset(0)[0];
137
                        } catch(IndexOutOfBoundsException e) {
138
                                //En ocasiones, sobre todo con servicios remotos al pedir un datasource da una excepci?n de este tipo
139
                                //se supone que es porque hay un refresco en el mismo momento de la petici?n por lo que como es m?s lento de
140
                                //gestionar pilla a la capa sin datasources asociados ya que est? reasignandolo. Si volvemos a pedirlo debe
141
                                //haberlo cargado ya.
142
                                try {
143
                                        Thread.sleep(200);
144
                                } catch (InterruptedException e1) {
145
                                }
146
                        }
147
                        limitNumberOfRequests --;
148
                }
149
                
150
                if(rds == null) {
151
                        //RasterToolsUtil.messageBoxError("error_load_layer", this, new Exception("Error writing RMF. limitNumberOfRequests=" + limitNumberOfRequests));
152
                        return;
153
                }
154
                
155
                RmfBlocksManager manager = rds.getRmfBlocksManager();
156

    
157
                RasterFilterList rasterFilterList = rasterSE.getRenderFilterList();
158

    
159
                ColorTableFilter colorTableFilter = (ColorTableFilter) rasterFilterList.getByName(ColorTableFilter.names[0]);
160
                if (colorTableFilter != null) {
161
                        GridPalette gridPalette = new GridPalette((ColorTable) colorTableFilter.getColorTable().clone());
162

    
163
                        ColorTableRmfSerializer ser = new ColorTableRmfSerializer(gridPalette);
164
                        manager.setPath(fileName);
165

    
166
                        if (!manager.checkRmf())
167
                                return;
168
                        manager.addClient(ser);
169
                        try {
170
                                RasterUtilities.copyFile(manager.getPath(), manager.getPath() + "~");
171
                                manager.write();
172
                        } catch (FileNotFoundException e) {
173
                                e.printStackTrace();
174
                        } catch (IOException e) {
175
                                e.printStackTrace();
176
                        }
177
                        manager.removeClient(ser.getClass());
178
                }
179
        }
180

    
181
        /**
182
         * M?todo donde se ejecutar? el Thread, aqu? se genera el recorte
183
         */
184
        public void run() {
185
                try {
186
                        RasterTaskQueue.register(rasterTask);
187

    
188
                        long t2;
189
                        long t1 = new java.util.Date().getTime();
190

    
191
                        IRasterDataSource d = rasterSE.getDataSource().copy();
192
                        BufferFactory bufferFactory = new BufferFactory(d);
193
                        bufferFactory.setDrawableBands(getDrawableBands());
194

    
195
                        IBuffer buffer = null;
196

    
197
                        if(        getInterpolationMethod() != BufferInterpolation.INTERPOLATION_Undefined &&
198
                                        getInterpolationMethod() != BufferInterpolation.INTERPOLATION_NearestNeighbour) {
199
                                try {
200
                                        bufferFactory.setAreaOfInterest(dValues[0], dValues[3], dValues[2] - dValues[0], dValues[1] - dValues[3]);
201
                                } catch (InvalidSetViewException e) {
202
                                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido asignar la vista al inicial el proceso de recorte.", e);
203
                                }
204
                                buffer = bufferFactory.getRasterBuf();
205
                                buffer = ((RasterBuffer)buffer).getAdjustedWindow(resolutionWidth, resolutionHeight, getInterpolationMethod());
206
                        } else {
207
                                try {
208
                                        bufferFactory.setAreaOfInterest(dValues[0], dValues[3], Math.abs(dValues[2] - dValues[0]), Math.abs(dValues[1] - dValues[3]), resolutionWidth, resolutionHeight);
209
                                        buffer = bufferFactory.getRasterBuf();
210
                                } catch (InvalidSetViewException e) {
211
                                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido asignar la vista al inicial el proceso de recorte.", e);
212
                                }
213
                        }
214
                        //TODO: FUNCIONALIDAD: Poner los getWriter con la proyecci?n del fichero fuente
215
                        String finalFileName = "";
216
                        if (isOneLayerPerBand()) {
217
                                long[] milis = new long[drawableBands.length];
218
                                for (int i = 0; i < drawableBands.length; i++) {
219
                                        finalFileName = fileName + "_B" + drawableBands[i] + ".tif";
220
                                        writerBufferServer.setBuffer(buffer, i);
221
                                        Params p = null;
222
                                        if (params == null)
223
                                                p = GeoRasterWriter.getWriter(finalFileName).getParams();
224
                                        else
225
                                                p = params;
226
                                        grw = GeoRasterWriter.getWriter(writerBufferServer, finalFileName, 1,
227
                                                        getAffineTransform(), buffer.getWidth(), buffer.getHeight(),
228
                                                        buffer.getDataType(), p, null);
229
                                        grw.setWkt(d.getWktProjection());
230
                                        grw.dataWrite();
231
                                        grw.writeClose();
232
                                        saveToRmf(finalFileName);
233
                                        t2 = new java.util.Date().getTime();
234
                                        milis[i] = (t2 - t1);
235
                                        cutFinalize(finalFileName, milis[i]);
236
                                        t1 = new java.util.Date().getTime();
237
                                }
238
                                if (incrementableTask != null) {
239
                                        incrementableTask.processFinalize();
240
                                        incrementableTask = null;
241
                                }
242
                                
243
                                for (int i = 0; i < drawableBands.length; i++) {
244
                                        if (externalActions != null) {
245
                                                RasterModule.layerCount++;
246
                                                externalActions.end(new Object[]{fileName, new Long(milis[i])});
247
                                        }
248
                                }
249
                        } else {
250
                                writerBufferServer.setBuffer(buffer, -1);
251
                                if (params == null) {
252
                                        finalFileName = fileName + ".tif";
253
                                        params = GeoRasterWriter.getWriter(finalFileName).getParams();
254
                                } else
255
                                        finalFileName = fileName;
256
                                grw = GeoRasterWriter.getWriter(writerBufferServer, finalFileName,
257
                                                buffer.getBandCount(), getAffineTransform(), buffer.getWidth(),
258
                                                buffer.getHeight(), buffer.getDataType(), params, null);
259
                                grw.setWkt(d.getWktProjection());
260
                                grw.dataWrite();
261
                                grw.writeClose();
262
                                saveToRmf(finalFileName);
263
                                t2 = new java.util.Date().getTime();
264
                                if (incrementableTask != null) {
265
                                        incrementableTask.processFinalize();
266
                                        incrementableTask = null;
267
                                }
268
                                //Damos tiempo a parar el Thread del incrementable para que no se cuelgue la ventana
269
                                //El tiempo es como m?nimo el de un bucle de del run de la tarea incrementable
270
                                Thread.sleep(600); 
271
                                cutFinalize(finalFileName, (t2 - t1));
272
                        }
273

    
274
                        d.close();
275
                } catch (NotSupportedExtensionException e) {
276
                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido obtener el writer. Extensi?n no soportada", e);
277
                } catch (RasterDriverException e) {
278
                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido obtener el writer.", e);
279
                } catch (IOException e) {
280
                        Logger.getLogger(this.getClass().getName()).debug("Error en la escritura en GeoRasterWriter.", e);
281
                } catch (InterruptedException e) {
282
                        if (externalActions != null)
283
                                externalActions.interrupted();
284
                        Thread.currentThread().interrupt();
285
                } finally {
286
                        RasterTaskQueue.remove(rasterTask);
287
                        if (incrementableTask != null)
288
                                incrementableTask.processFinalize();
289
                }
290
        }
291

    
292
        /**
293
         * Establece el <code>IncrementableTask</code>
294
         * @param value
295
         */
296
        public void setIncrementableTask(IncrementableTask value) {
297
                incrementableTask = value;
298
                incrementableTask.addIncrementableListener(this);
299
        }
300

    
301
        /*
302
         * (non-Javadoc)
303
         * @see org.gvsig.gui.beans.incrementabletask.IncrementableListener#actionCanceled(org.gvsig.gui.beans.incrementabletask.IncrementableEvent)
304
         */
305
        public void actionCanceled(IncrementableEvent e) {
306
                rasterTask.setEvent(new CancelEvent(this));
307
        }
308

    
309
        /**
310
         * Acciones que se realizan al finalizar de crear los recortes de imagen.
311
         * Este m?todo es llamado por el thread TailRasterProcess al finalizar.
312
         */
313
        private void cutFinalize(String fileName, long milis) {
314
                /*if (!isLoadedInToc()) {
315
                        externalActions.end(new Object[]{fileName, new Long(milis)});
316
                        return;
317
                }*/
318
                
319
                if (!new File(fileName).exists())
320
                        return;
321
                
322
                if(RasterToolsUtil.messageBoxYesOrNot("cargar_toc", this)) {
323
                        try {
324
                                RasterToolsUtil.loadLayer(viewName, fileName, null);
325
                        } catch (RasterNotLoadException e) {
326
                                RasterToolsUtil.messageBoxError("error_load_layer", this, e);
327
                        }
328
                }
329
                
330
                if (externalActions != null) {
331
                        RasterModule.layerCount++;
332
                        externalActions.end(new Object[]{fileName, new Long(milis)});
333
                }
334
        }
335

    
336
        /**
337
         * Asigna los par?metros si estos han de ser cambiados. En caso de
338
         * que no se asignen se usaran los que tiene el driver por defecto.
339
         * @param params Par?metros del driver de escritura.
340
         */
341
        public void setParams(Params params) {
342
                this.params = params;
343
        }
344

    
345
        public boolean isLoadedInToc() {
346
                return loadedInToc;
347
        }
348

    
349
        public void setLoadedInToc(boolean loadedInToc) {
350
                this.loadedInToc = loadedInToc;
351
        }
352

    
353
        public int[] getDrawableBands() {
354
                return drawableBands;
355
        }
356

    
357
        public void setDrawableBands(int[] drawableBands) {
358
                this.drawableBands = drawableBands;
359
        }
360

    
361
        public boolean isOneLayerPerBand() {
362
                return oneLayerPerBand;
363
        }
364

    
365
        public void setOneLayerPerBand(boolean oneLayerPerBand) {
366
                this.oneLayerPerBand = oneLayerPerBand;
367
        }
368

    
369
        public int getInterpolationMethod() {
370
                return interpolationMethod;
371
        }
372

    
373
        public void setInterpolationMethod(int interpolationMethod) {
374
                this.interpolationMethod = interpolationMethod;
375
        }
376

    
377
        public AffineTransform getAffineTransform() {
378
                return affineTransform;
379
        }
380

    
381
        public void setAffineTransform(AffineTransform affineTransform) {
382
                this.affineTransform = affineTransform;
383
        }
384

    
385
        /**
386
         * Obtiene el objeto para ejecutar acciones externar.
387
         * @param IProcessActions
388
         */
389
        public IProcessActions getActions() {
390
                return externalActions;
391
        }
392

    
393
        /**
394
         * Asigna el objeto para ejecutar acciones externar.
395
         * @param IProcessActions
396
         */
397
        public void setActions(IProcessActions actions) {
398
                this.externalActions = actions;
399
        }
400

    
401
        public void actionResumed(IncrementableEvent e) {}
402
        public void actionSuspended(IncrementableEvent e) {}
403
}