Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / util / process / ClippingProcess.java @ 19568

History | View | Annotate | Download (13.8 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.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.raster.Configuration;
29
import org.gvsig.raster.RasterProcess;
30
import org.gvsig.raster.buffer.BufferFactory;
31
import org.gvsig.raster.buffer.BufferInterpolation;
32
import org.gvsig.raster.buffer.RasterBuffer;
33
import org.gvsig.raster.buffer.WriterBufferServer;
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.io.RasterDriverException;
42
import org.gvsig.raster.dataset.io.rmf.RmfBlocksManager;
43
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
44
import org.gvsig.raster.datastruct.ColorTable;
45
import org.gvsig.raster.datastruct.serializer.ColorTableRmfSerializer;
46
import org.gvsig.raster.datastruct.serializer.NoDataRmfSerializer;
47
import org.gvsig.raster.grid.GridPalette;
48
import org.gvsig.raster.grid.filter.RasterFilterList;
49
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
50
import org.gvsig.raster.util.RasterNotLoadException;
51
import org.gvsig.raster.util.RasterToolsUtil;
52
import org.gvsig.raster.util.RasterUtilities;
53
/**
54
 * <code>ClippingProcess</code> es un proceso que usa un <code>Thread</code>
55
 * para aplicar un recorte a una capa y guardarlo en disco. Muestra una barra
56
 * de incremento informativa.
57
 *
58
 * @version 24/04/2007
59
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
60
 */
61
public class ClippingProcess extends RasterProcess {
62
        private String                        fileName            = "";
63
        private WriterBufferServer            writerBufferServer  = null;
64
        private FLyrRasterSE                  rasterSE            = null;
65
        private AffineTransform               affineTransform     = new AffineTransform();
66
        private boolean                       oneLayerPerBand     = false;
67
        private int[]                         drawableBands       = { 0, 1, 2 };
68
        private int[]                         dValues             = null;
69
        private GeoRasterWriter               grw                 = null;
70
        private int                           interpolationMethod = BufferInterpolation.INTERPOLATION_Undefined;
71
        private String                        viewName            = "";
72
        private Params                        params              = null;
73
        private DatasetColorInterpretation    colorInterp         = null;
74

    
75
        /**
76
         * Variables de la resoluci?n de salida
77
         */
78
        private int                           resolutionWidth     = 0;
79
        private int                           resolutionHeight    = 0;
80
        
81
        private IBuffer                       buffer              = null;
82

    
83
        /**
84
         * Par?metros obligatorios al proceso:
85
         * <UL>
86
         * <LI>filename: Nombre del fichero de salida</LI>
87
         * <LI>datawriter: Escritor de datos</LI>
88
         * <LI>viewname: Nombre de la vista sobre la que se carga la capa al acabar el proceso</LI>
89
         * <LI>pixelcoordinates: Coordenadas pixel del recorte</LI>
90
         * <LI>layer: Capa de entrada para el recorte</LI>
91
         * <LI>drawablebands: Bandas de entrada</LI>
92
         * <LI>onelayerperband: booleano que informa de si escribimos una banda por fichero de salida o todas en un fichero</LI>
93
         * <LI>interpolationmethod: M?todo de interpolaci?n.</LI>
94
         * <LI>affinetransform: Transformaci?n que informa al dataset de salida de su referencia geografica</LI>
95
         * <LI>resolution: Ancho y alto de la capa de salida</LI>
96
         * </UL> 
97
         */
98
        public void init() {
99
                fileName = getStringParam("filename");
100
                writerBufferServer = (WriterBufferServer) getParam("datawriter");
101
                viewName = getStringParam("viewname");
102
                dValues = getIntArrayParam("pixelcoordinates");
103
                rasterSE = getLayerParam("layer");
104
                drawableBands = getIntArrayParam("drawablebands");
105
                oneLayerPerBand = getBooleanParam("onelayerperband");
106
                interpolationMethod = getIntParam("interpolationmethod");
107
                affineTransform = (AffineTransform)getParam("affinetransform");
108
                colorInterp = (DatasetColorInterpretation)getParam("colorInterpretation");
109
                if(getIntArrayParam("resolution") != null) {
110
                        resolutionWidth = getIntArrayParam("resolution")[0];
111
                        resolutionHeight = getIntArrayParam("resolution")[1];
112
                }
113
                params = (Params) getParam("driverparams");
114
        }
115

    
116
        /**
117
         * Salva la tabla de color al fichero rmf.
118
         * @param fName
119
         * @throws IOException
120
         */
121
        private void saveToRmf(String fileName) {
122
                fileName = RasterUtilities.getNameWithoutExtension(fileName) + ".rmf";
123

    
124
                RasterDataset rds = null;
125
                int limitNumberOfRequests = 20;
126
                while (rds == null && limitNumberOfRequests > 0) {
127
                        try {
128
                                rds = rasterSE.getDataSource().getDataset(0)[0];
129
                        } catch (IndexOutOfBoundsException e) {
130
                                //En ocasiones, sobre todo con servicios remotos al pedir un datasource da una excepci?n de este tipo
131
                                //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
132
                                //gestionar pilla a la capa sin datasources asociados ya que est? reasignandolo. Si volvemos a pedirlo debe
133
                                //haberlo cargado ya.
134
                                try {
135
                                        Thread.sleep(200);
136
                                } catch (InterruptedException e1) {
137
                                }
138
                        }
139
                        limitNumberOfRequests--;
140
                }
141
                
142
                if (rds == null) {
143
                        //RasterToolsUtil.messageBoxError("error_load_layer", this, new Exception("Error writing RMF. limitNumberOfRequests=" + limitNumberOfRequests));
144
                        return;
145
                }
146
                
147
                RmfBlocksManager manager = rds.getRmfBlocksManager();
148

    
149
                RasterFilterList rasterFilterList = rasterSE.getRenderFilterList();
150

    
151
                manager.setPath(fileName);
152

    
153
                if (!manager.checkRmf())
154
                        return;
155

    
156
                // A?adimos el serializador de NoData
157
                if (Configuration.getValue("nodata_transparency_enabled", Boolean.FALSE).booleanValue()) {
158
                        NoDataRmfSerializer ser = new NoDataRmfSerializer(Double.valueOf(rasterSE.getNoDataValue(0)));
159
                        manager.addClient(ser);
160
                }
161
                
162
                // A?adimos el serializador para tablas de color
163
                ColorTableFilter colorTableFilter = (ColorTableFilter) rasterFilterList.getByName(ColorTableFilter.names[0]);
164
                if (colorTableFilter != null) {
165
                        GridPalette gridPalette = new GridPalette((ColorTable) colorTableFilter.getColorTable().clone());
166
                        ColorTableRmfSerializer ser = new ColorTableRmfSerializer(gridPalette);
167
                        manager.addClient(ser);
168
                }
169

    
170
                try {
171
                        manager.write(true);
172
                } catch (FileNotFoundException e) {
173
                        RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
174
                } catch (IOException e) {
175
                        RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
176
                }
177

    
178
                manager.deleteAllClients();
179
        }
180

    
181
        /**
182
         * Tarea de recorte
183
         */
184
        public void process() throws InterruptedException {
185
                IRasterDataSource dsetCopy = null;
186
                try {
187
                        long t2;
188
                        long t1 = new java.util.Date().getTime();
189

    
190
                        insertLineLog(RasterToolsUtil.getText(this, "leyendo_raster"));
191

    
192
                        dsetCopy = rasterSE.getDataSource().newDataset();
193
                        BufferFactory bufferFactory = new BufferFactory(dsetCopy);
194
                        bufferFactory.setDrawableBands(drawableBands);
195
        
196
                        if(        interpolationMethod != BufferInterpolation.INTERPOLATION_Undefined &&
197
                                        interpolationMethod != BufferInterpolation.INTERPOLATION_NearestNeighbour) {
198
                                try {
199
                                        if (RasterBuffer.isBufferTooBig(new double[] { dValues[0], dValues[3], dValues[2], dValues[1] }, drawableBands.length))
200
                                                bufferFactory.setReadOnly(true);
201

    
202
                                        bufferFactory.setAreaOfInterest(dValues[0], dValues[3], dValues[2] - dValues[0], dValues[1] - dValues[3]);
203
                                } catch (InvalidSetViewException e) {
204
                                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido asignar la vista al inicial el proceso de recorte.", e);
205
                                }
206
                                buffer = bufferFactory.getRasterBuf();
207

    
208
                                insertLineLog(RasterToolsUtil.getText(this, "interpolando"));
209

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

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

    
293
                } catch (NotSupportedExtensionException e) {
294
                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido obtener el writer. Extensi?n no soportada", e);
295
                } catch (RasterDriverException e) {
296
                        Logger.getLogger(this.getClass().getName()).debug("No se ha podido obtener el writer.", e);
297
                } catch (IOException e) {
298
                        Logger.getLogger(this.getClass().getName()).debug("Error en la escritura en GeoRasterWriter.", e);
299
                } finally {
300
                        if (dsetCopy != null)
301
                                dsetCopy.close();
302
                        buffer = null;
303
                }
304
        }
305
        
306
        /**
307
         * Acciones que se realizan al finalizar de crear los recortes de imagen.
308
         * Este m?todo es llamado por el thread TailRasterProcess al finalizar.
309
         */
310
        private void cutFinalize(String fileName, long milis) {
311
                if (!new File(fileName).exists())
312
                        return;
313

    
314
                if (RasterToolsUtil.messageBoxYesOrNot("cargar_toc", this)) {
315
                        try {
316
                                RasterToolsUtil.loadLayer(viewName, fileName, null);
317
                        } catch (RasterNotLoadException e) {
318
                                RasterToolsUtil.messageBoxError("error_load_layer", this, e);
319
                        }
320
                }
321

    
322
                if (externalActions != null)
323
                        externalActions.end(new Object[]{fileName, new Long(milis)});
324
        }
325

    
326
        /*
327
         * (non-Javadoc)
328
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
329
         */
330
        public int getPercent() {
331
                return (writerBufferServer != null) ? writerBufferServer.getPercent() : 0;
332
        }
333

    
334
        /*
335
         * (non-Javadoc)
336
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
337
         */
338
        public String getTitle() {
339
                return RasterToolsUtil.getText(this, "incremento_recorte");
340
        }
341
}