Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / util / process / ClippingProcess.java @ 30122

History | View | Annotate | Download (15.2 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.raster.util.process;
20

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

    
25
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
26
import org.gvsig.raster.Configuration;
27
import org.gvsig.raster.RasterProcess;
28
import org.gvsig.raster.buffer.BufferFactory;
29
import org.gvsig.raster.buffer.BufferInterpolation;
30
import org.gvsig.raster.buffer.RasterBuffer;
31
import org.gvsig.raster.buffer.WriterBufferServer;
32
import org.gvsig.raster.dataset.GeoRasterWriter;
33
import org.gvsig.raster.dataset.IBuffer;
34
import org.gvsig.raster.dataset.IRasterDataSource;
35
import org.gvsig.raster.dataset.InvalidSetViewException;
36
import org.gvsig.raster.dataset.NotSupportedExtensionException;
37
import org.gvsig.raster.dataset.Params;
38
import org.gvsig.raster.dataset.RasterDataset;
39
import org.gvsig.raster.dataset.io.RasterDriverException;
40
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
41
import org.gvsig.raster.dataset.serializer.RmfSerializerException;
42
import org.gvsig.raster.datastruct.ColorTable;
43
import org.gvsig.raster.datastruct.NoData;
44
import org.gvsig.raster.grid.GridPalette;
45
import org.gvsig.raster.grid.filter.RasterFilterList;
46
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
47
import org.gvsig.raster.util.ExternalCancellable;
48
import org.gvsig.raster.util.RasterNotLoadException;
49
import org.gvsig.raster.util.RasterToolsUtil;
50

    
51
import com.iver.cit.gvsig.fmap.layers.FLayer;
52
/**
53
 * <code>ClippingProcess</code> es un proceso que usa un <code>Thread</code>
54
 * para aplicar un recorte a una capa y guardarlo en disco. Muestra una barra
55
 * de incremento informativa.
56
 *
57
 * @version 24/04/2007
58
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
59
 */
60
public class ClippingProcess extends RasterProcess {
61
        private String                        fileName            = "";
62
        private WriterBufferServer            writerBufferServer  = null;
63
        private FLyrRasterSE                  rasterSE            = null;
64
        private AffineTransform               affineTransform     = new AffineTransform();
65
        private boolean                       oneLayerPerBand     = false;
66
        private int[]                         drawableBands       = { 0, 1, 2 };
67
        private int[]                         pValues             = null;
68
        private GeoRasterWriter               grw                 = null;
69
        private int                           interpolationMethod = BufferInterpolation.INTERPOLATION_Undefined;
70
        private String                        viewName            = "";
71
        private Params                        params              = null;
72
        private DatasetColorInterpretation    colorInterp         = null;
73

    
74
        private double[]                      wcValues             = null;
75
        
76
        /**
77
         * Variables de la resoluci?n de salida
78
         */
79
        private int                           resolutionWidth     = 0;
80
        private int                           resolutionHeight    = 0;
81
        
82
        private IBuffer                       buffer              = null;
83
        private boolean                       showEndDialog       = true;
84
        private ExternalCancellable           cancellableObj      = null;
85

    
86
        /**
87
         * Par?metros obligatorios al proceso:
88
         * <UL>
89
         * <LI>filename: Nombre del fichero de salida</LI>
90
         * <LI>datawriter: Escritor de datos</LI>
91
         * <LI>viewname: Nombre de la vista sobre la que se carga la capa al acabar el proceso</LI>
92
         * <LI>pixelcoordinates: Coordenadas pixel del recorte (ulx, uly, lrx, lry)</LI>
93
         * <LI>layer: Capa de entrada para el recorte</LI>
94
         * <LI>drawablebands: Bandas de entrada</LI>
95
         * <LI>onelayerperband: booleano que informa de si escribimos una banda por fichero de salida o todas en un fichero</LI>
96
         * <LI>interpolationmethod: M?todo de interpolaci?n.</LI>
97
         * <LI>affinetransform: Transformaci?n que informa al dataset de salida de su referencia geografica</LI>
98
         * <LI>resolution: Ancho y alto de la capa de salida</LI>
99
         * </UL> 
100
         */
101
        public void init() {
102
                fileName = getStringParam("filename");
103
                writerBufferServer = (WriterBufferServer) getParam("datawriter");
104
                viewName = getStringParam("viewname");
105
                pValues = getIntArrayParam("pixelcoordinates");
106
                wcValues = getDoubleArrayParam("realcoordinates");
107
                rasterSE = getLayerParam("layer");
108
                drawableBands = getIntArrayParam("drawablebands");
109
                oneLayerPerBand = getBooleanParam("onelayerperband");
110
                interpolationMethod = getIntParam("interpolationmethod");
111
                affineTransform = (AffineTransform)getParam("affinetransform");
112
                colorInterp = (DatasetColorInterpretation)getParam("colorInterpretation");
113
                if(getIntArrayParam("resolution") != null) {
114
                        resolutionWidth = getIntArrayParam("resolution")[0];
115
                        resolutionHeight = getIntArrayParam("resolution")[1];
116
                }
117
                params = (Params) getParam("driverparams");
118
                showEndDialog = getBooleanParam("showenddialog");
119
                Object obj = taskParams.get("cancellable");
120
                if(obj != null)
121
                        cancellableObj = (ExternalCancellable)obj;
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
                RasterDataset rds = null;
131
                int limitNumberOfRequests = 20;
132
                while (rds == null && limitNumberOfRequests > 0) {
133
                        try {
134
                                rds = rasterSE.getDataSource().getDataset(0)[0];
135
                        } catch (IndexOutOfBoundsException e) {
136
                                //En ocasiones, sobre todo con servicios remotos al pedir un datasource da una excepci?n de este tipo
137
                                //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
138
                                //gestionar pilla a la capa sin datasources asociados ya que est? reasignandolo. Si volvemos a pedirlo debe
139
                                //haberlo cargado ya.
140
                                try {
141
                                        Thread.sleep(200);
142
                                } catch (InterruptedException e1) {
143
                                }
144
                        }
145
                        limitNumberOfRequests--;
146
                }
147
                
148
                if (rds == null) {
149
                        //RasterToolsUtil.messageBoxError("error_load_layer", this, new Exception("Error writing RMF. limitNumberOfRequests=" + limitNumberOfRequests));
150
                        return;
151
                }
152

    
153
                RasterFilterList rasterFilterList = rasterSE.getRenderFilterList();
154

    
155
                // Guardamos en el RMF el valor NoData
156
                if (Configuration.getValue("nodata_transparency_enabled", Boolean.FALSE).booleanValue()) {
157
                        try {
158
                                RasterDataset.saveObjectToRmfFile(fileName, NoData.class, new NoData(rasterSE.getNoDataValue(), rasterSE.getNoDataType(), rasterSE.getDataType()[0]));
159
                        } catch (RmfSerializerException e) {
160
                                RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
161
                        }
162
                }
163

    
164
                // Guardamos en el RMF la tabla de color
165
                ColorTableFilter colorTableFilter = (ColorTableFilter) rasterFilterList.getByName(ColorTableFilter.names[0]);
166
                if (colorTableFilter != null) {
167
                        GridPalette gridPalette = new GridPalette((ColorTable) colorTableFilter.getColorTable().clone());
168
                        try {
169
                                RasterDataset.saveObjectToRmfFile(fileName, ColorTable.class, (ColorTable) gridPalette);
170
                        } catch (RmfSerializerException e) {
171
                                RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
172
                        }
173
                }
174
        }
175

    
176
        /**
177
         * Tarea de recorte
178
         */
179
        public void process() throws InterruptedException {
180
                IRasterDataSource dsetCopy = null;
181
                if(rasterSE != null)
182
                        rasterSE.setReadingData(Thread.currentThread().toString());
183
                
184
                try {
185
                        long t2;
186
                        long t1 = new java.util.Date().getTime();
187

    
188
                        insertLineLog(RasterToolsUtil.getText(this, "leyendo_raster"));
189

    
190
                        dsetCopy = rasterSE.getDataSource().newDataset();
191
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
192
                        bufferFactory.setDrawableBands(drawableBands);
193
        
194
                        if(interpolationMethod != BufferInterpolation.INTERPOLATION_Undefined) {
195
                                try {
196
                                        if(pValues != null) {
197
                                                if (RasterBuffer.isBufferTooBig(new double[] { pValues[0], pValues[3], pValues[2], pValues[1] }, drawableBands.length))
198
                                                        bufferFactory.setReadOnly(true);
199
                                                bufferFactory.setAreaOfInterest(pValues[0], pValues[3], pValues[2] - pValues[0], pValues[1] - pValues[3]);
200
                                        } else if(wcValues != null) {
201
                                                //if (RasterBuffer.isBufferTooBig(new double[] { wcValues[0], wcValues[3], wcValues[2], wcValues[1] }, rasterSE.getCellSize(), drawableBands.length))
202
                                                        bufferFactory.setReadOnly(true);
203
                                                bufferFactory.setAreaOfInterest(wcValues[0], wcValues[1], Math.abs(wcValues[0] - wcValues[2]), Math.abs(wcValues[1] - wcValues[3]));
204
                                        }
205
                                } catch (InvalidSetViewException e) {
206
                                        RasterToolsUtil.messageBoxError("No se ha podido asignar la vista al inicial el proceso de recorte.", this, e);
207
                                }
208
                                buffer = bufferFactory.getRasterBuf();
209

    
210
                                insertLineLog(RasterToolsUtil.getText(this, "interpolando"));
211

    
212
                                buffer = ((RasterBuffer) buffer).getAdjustedWindow(resolutionWidth, resolutionHeight, interpolationMethod);
213
                        } else {
214
                                try {
215
                                        if (RasterBuffer.isBufferTooBig(new double[] { 0, 0, resolutionWidth, resolutionHeight }, drawableBands.length))
216
                                                bufferFactory.setReadOnly(true);
217
                                        if(pValues != null) 
218
                                                bufferFactory.setAreaOfInterest(pValues[0], pValues[3], Math.abs(pValues[2] - pValues[0]) + 1, Math.abs(pValues[1] - pValues[3]) + 1, resolutionWidth, resolutionHeight);
219
                                        else if(wcValues != null) 
220
                                                bufferFactory.setAreaOfInterest(wcValues[0], wcValues[1], wcValues[2], wcValues[3], resolutionWidth, resolutionHeight);
221
                                        buffer = bufferFactory.getRasterBuf();
222
                                } catch (InvalidSetViewException e) {
223
                                        RasterToolsUtil.messageBoxError("No se ha podido asignar la vista al inicial el proceso de recorte.", this, e);
224
                                }
225
                        }
226
                        //TODO: FUNCIONALIDAD: Poner los getWriter con la proyecci?n del fichero fuente
227
                        
228
                        insertLineLog(RasterToolsUtil.getText(this, "salvando_imagen"));
229

    
230
                        String finalFileName = "";
231
                        if (oneLayerPerBand) {
232
                                long[] milis = new long[drawableBands.length];
233
                                String[] fileNames = new String[drawableBands.length];
234
                                for (int i = 0; i < drawableBands.length; i++) {
235
                                        fileNames[i] = fileName + "_B" + drawableBands[i] + ".tif";
236
                                        writerBufferServer.setBuffer(buffer, i);
237
                                        Params p = null;
238
                                        if (params == null)
239
                                                p = GeoRasterWriter.getWriter(fileNames[i]).getParams();
240
                                        else
241
                                                p = params;
242
                                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileNames[i], 1,
243
                                                        affineTransform, buffer.getWidth(), buffer.getHeight(),
244
                                                        buffer.getDataType(), p, null);
245
                                        grw.setColorBandsInterpretation(new String[]{DatasetColorInterpretation.GRAY_BAND});
246
                                        grw.setWkt(dsetCopy.getWktProjection());
247
                                        grw.setCancellableRasterDriver(cancellableObj);
248
                                        grw.dataWrite();
249
                                        grw.writeClose();
250
                                        saveToRmf(fileNames[i]);
251
                                        t2 = new java.util.Date().getTime();
252
                                        milis[i] = (t2 - t1);
253
                                        t1 = new java.util.Date().getTime();
254
                                }
255
                                if (incrementableTask != null) {
256
                                        incrementableTask.processFinalize();
257
                                        incrementableTask = null;
258
                                }
259
                                if(viewName != null) {
260
                                        if (RasterToolsUtil.messageBoxYesOrNot("cargar_toc", this)) {
261
                                                try {
262
                                                        for (int i = 0; i < drawableBands.length; i++) {
263
                                                                FLayer lyr = RasterToolsUtil.loadLayer(viewName, fileNames[i], null);
264
                                                                if(lyr != null && lyr instanceof FLyrRasterSE)
265
                                                                        ((FLyrRasterSE)lyr).setRois(rasterSE.getRois());
266
                                                        }
267
                                                } catch (RasterNotLoadException e) {
268
                                                        RasterToolsUtil.messageBoxError("error_load_layer", this, e);
269
                                                }
270
                                        }
271
                                }
272
                                for (int i = 0; i < drawableBands.length; i++) {
273
                                        if (externalActions != null)
274
                                                externalActions.end(new Object[] { fileName + "_B" + drawableBands[i] + ".tif", new Long(milis[i]) });
275
                                }
276
                        } else {
277
                                writerBufferServer.setBuffer(buffer, -1);
278
                                if (params == null) {
279
                                        finalFileName = fileName + ".tif";
280
                                        params = GeoRasterWriter.getWriter(finalFileName).getParams();
281
                                } else
282
                                        finalFileName = fileName;
283
                                grw = GeoRasterWriter.getWriter(writerBufferServer, finalFileName,
284
                                                buffer.getBandCount(), affineTransform, buffer.getWidth(),
285
                                                buffer.getHeight(), buffer.getDataType(), params, null);
286
                                if(colorInterp != null)
287
                                        grw.setColorBandsInterpretation(colorInterp.getValues());
288
                                grw.setWkt(dsetCopy.getWktProjection());
289
                                grw.setCancellableRasterDriver(cancellableObj);
290
                                grw.dataWrite();
291
                                grw.writeClose();
292
                                saveToRmf(finalFileName);
293
                                t2 = new java.util.Date().getTime();
294
                                if (incrementableTask != null) {
295
                                        incrementableTask.processFinalize();
296
                                        incrementableTask = null;
297
                                }
298
                                //Damos tiempo a parar el Thread del incrementable para que no se cuelgue la ventana
299
                                //El tiempo es como m?nimo el de un bucle del run de la tarea incrementable
300
                                Thread.sleep(600);
301
                                cutFinalize(finalFileName, (t2 - t1));
302
                        }
303

    
304
                } catch (NotSupportedExtensionException e) {
305
                        RasterToolsUtil.messageBoxError("No se ha podido obtener el writer. Extensi?n no soportada", this, e);
306
                } catch (RasterDriverException e) {
307
                        RasterToolsUtil.messageBoxError("No se ha podido obtener el writer.", this, e);
308
                } catch (IOException e) {
309
                        RasterToolsUtil.messageBoxError("Error en la escritura en GeoRasterWriter.", this, e);
310
                } finally {
311
                        if(rasterSE != null)
312
                                rasterSE.setReadingData(null);
313
                        if (dsetCopy != null)
314
                                dsetCopy.close();
315
                        buffer = null;
316
                }
317
        }
318
        
319
        /**
320
         * Acciones que se realizan al finalizar de crear los recortes de imagen.
321
         * Este m?todo es llamado por el thread TailRasterProcess al finalizar.
322
         */
323
        private void cutFinalize(String fileName, long milis) {
324
                if (!new File(fileName).exists())
325
                        return;
326

    
327
                if(viewName != null) {
328
                        if (RasterToolsUtil.messageBoxYesOrNot("cargar_toc", this)) {
329

    
330
                                try {
331
                                        FLayer lyr = RasterToolsUtil.loadLayer(viewName, fileName, null);
332
                                        if(lyr != null && lyr instanceof FLyrRasterSE)
333
                                                ((FLyrRasterSE)lyr).setRois(rasterSE.getRois());
334
                                } catch (RasterNotLoadException e) {
335
                                        RasterToolsUtil.messageBoxError("error_load_layer", this, e);
336
                                }
337
                        }
338
                }
339

    
340
                if (showEndDialog && externalActions != null)
341
                        externalActions.end(new Object[]{fileName, new Long(milis)});
342
        }
343

    
344
        /*
345
         * (non-Javadoc)
346
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
347
         */
348
        public int getPercent() {
349
                if (buffer != null) {
350
                        BufferInterpolation interpolation = ((RasterBuffer) buffer).getLastInterpolation();
351
                        
352
                        if (interpolation != null)
353
                                if ((interpolation.getPercent() > 0) && (interpolation.getPercent() < 99))
354
                                        return interpolation.getPercent();
355
                }
356
                
357
                return (writerBufferServer != null) ? writerBufferServer.getPercent() : 0;
358
        }
359

    
360
        /*
361
         * (non-Javadoc)
362
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
363
         */
364
        public String getTitle() {
365
                return RasterToolsUtil.getText(this, "incremento_recorte");
366
        }
367
}