Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.algorithm / src / main / java / org / gvsig / raster / algorithm / process / ProcessUtils.java @ 2106

History | View | Annotate | Download (13.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
package org.gvsig.raster.algorithm.process;
23

    
24
import java.awt.Component;
25
import java.awt.geom.AffineTransform;
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.util.ArrayList;
29
import java.util.List;
30

    
31
import javax.swing.JOptionPane;
32

    
33
import org.gvsig.fmap.dal.coverage.RasterLocator;
34
import org.gvsig.fmap.dal.coverage.RasterManager;
35
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
36
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
37
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
38
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
39
import org.gvsig.fmap.dal.coverage.datastruct.Params;
40
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
41
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
42
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
43
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
44
import org.gvsig.fmap.dal.coverage.grid.ROI;
45
import org.gvsig.fmap.dal.coverage.store.DataServerWriter;
46
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
47
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
48
import org.gvsig.fmap.dal.coverage.store.RasterWriter;
49
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
50
import org.gvsig.i18n.Messages;
51
import org.slf4j.LoggerFactory;
52
/**
53
 * Clase base de todos los procesos raster. En ella se genstionan todas las
54
 * funciones comunes como incremento de la tarea, gesti?n de eventos a la tarea, 
55
 * par?metros de la tarea, etc ...
56
 * 
57
 * 18/12/2007
58
 * @author Nacho Brodin nachobrodin@gmail.com
59
 */
60
public abstract class ProcessUtils {
61
        /**
62
         * Registra un mensaje de error en el log de gvSIG
63
         * @param msg Mensaje a guardar en el log
64
         * @param parent Objeto que hizo disparar el mensaje
65
         * @param exception Excepcion que ha sido recogida
66
         */
67
        public void debug(String msg, Object parent, Exception exception) {
68
                if(parent != null)
69
                    LoggerFactory
70
            .getLogger(parent.getClass()).debug(Messages.getText(msg), exception);
71
        }
72
        
73
        /**
74
         * Shows a error dialog with a text and a accept button 
75
         * @param msg Message to show in the dialog
76
         * @param parentWindow Parent window
77
         */
78
        public void messageBoxError(String msg, Object parentWindow){
79
                String string = Messages.getText("accept");
80
                Object[] options = {string};
81
                JOptionPane.showOptionDialog((Component)parentWindow,
82
                                        "<html>" + Messages.getText(msg).replaceAll("\n", "<br>") + "</html>",
83
                                        Messages.getText("confirmacion"),
84
                                        JOptionPane.OK_OPTION,
85
                                        JOptionPane.ERROR_MESSAGE,
86
                                        null,
87
                                        options,
88
                                        string);
89
        }
90
        
91
        /**
92
         * Muestra un dialogo de error con un texto y un bot?n de aceptar. El error es
93
         * registrado en el log de gvSIG con la excepcion que se le pase por parametro
94
         * @param msg Mensaje a mostrar en el dialogo.
95
         * @param parentWindow Ventana desde la que se lanza el dialogo
96
         * @param exception Excepcion que ha sido recogida
97
         */
98
        public void messageBoxError(String msg, Object parentWindow, Exception exception) {
99
                debug(msg, parentWindow, exception);
100
                messageBoxError(msg, parentWindow);
101
        }
102
        
103
        /**
104
         * Muestra un dialogo de error con un texto y un bot?n de aceptar. Se le pasa como ?ltimo par?metros
105
         * una lista de excepciones que ser?n guardadas en el log
106
         * @param msg Mensaje a mostrar en el dialogo.
107
         * @param parentWindow Ventana desde la que se lanza el dialogo
108
         * @param exception Excepcion que ha sido recogida
109
         */
110
        public void messageBoxError(String msg, Object parentWindow, ArrayList<Exception> exception) {
111
                for (int i = 0; i < exception.size(); i++) 
112
                        debug(msg, parentWindow, exception.get(i));
113
                messageBoxError(msg, parentWindow);
114
        }
115
        
116
        /**
117
         * Exports a raster buffer to disk
118
         * @param sFilename
119
         * @param buf
120
         * @param cellsize
121
         * @param minX
122
         * @param minY
123
         * @return
124
         */
125
        public boolean exportRaster(final String sFilename, 
126
                        Buffer buf, 
127
                        Buffer alphaBuffer, 
128
                        double cellsize, 
129
                        double minX, 
130
                        double minY) {
131
                try {
132
                        RasterManager manager = RasterLocator.getManager();
133
                        final DataServerWriter writerBufferServer = manager.createDataServerWriter();
134
                        writerBufferServer.setBuffer(buf, -1);
135
                        int nBands = buf.getBandCount();
136
                        ColorInterpretation colorInterpretation = null;
137
                        if(alphaBuffer != null) {
138
                                writerBufferServer.setAlphaBuffer(alphaBuffer);
139
                                nBands ++;
140
                                colorInterpretation = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(
141
                                                new String[] { 
142
                                                                ColorInterpretation.RED_BAND, 
143
                                                                ColorInterpretation.GREEN_BAND, 
144
                                                                ColorInterpretation.BLUE_BAND,
145
                                                                ColorInterpretation.ALPHA_BAND});
146
                        } else {
147
                                if(nBands == 1)
148
                                        colorInterpretation = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(
149
                                                        new String[] { ColorInterpretation.GRAY_BAND });
150
                        }
151
                        final Params params = manager.createWriterParams(sFilename);
152
                        final AffineTransform affineTransform =
153
                                new AffineTransform(cellsize, 0, 0,
154
                                                -cellsize, minX, minY);
155

    
156
                        final RasterWriter writer = manager.createWriter(
157
                                                writerBufferServer, 
158
                                                sFilename,
159
                                                nBands, 
160
                                                affineTransform, 
161
                                                buf.getWidth(),
162
                                                buf.getHeight(), 
163
                                                buf.getDataType(), 
164
                                                params, 
165
                                                null);
166
                        if(colorInterpretation != null)
167
                                writer.setColorBandsInterpretation(colorInterpretation.getValues());
168
                        writer.dataWrite();
169
                        writer.writeClose();
170
                } catch (final Exception e) {
171
                        e.printStackTrace();
172
                        return false;
173
                }
174
                return true;
175
        }
176
        
177
        /**
178
         * Exports a raster buffer to disk
179
         * @param sFilename
180
         * @param buf
181
         * @param cellsize
182
         * @param minX
183
         * @param minY
184
         * @return
185
         */
186
        public boolean exportRaster(final String sFilename, 
187
                        Buffer buf, 
188
                        double cellsize, 
189
                        double minX, 
190
                        double minY) {
191
        return exportRaster(sFilename, buf, null, cellsize, minX, minY);
192
    }
193
        
194
        /**
195
         * Gets a list of rectangles which represents the pixel coordinates of each DataStore.
196
         * This rectangle is the area that intersects with the other DataStores in the         list.
197
         * @param dataStoreList
198
         * @return
199
         */
200
        protected Rectangle2D[] getIntersectionInPxCoords(RasterDataStore[] dataStoreList) {
201
                Extent extentIntersect = null;
202
                int nRectangles = 0;
203
                for (int i = 0; i < dataStoreList.length; i++) {
204
                        if(dataStoreList[i] != null) {
205
                                if(extentIntersect == null)
206
                                        extentIntersect = dataStoreList[i].getExtent();
207
                                else
208
                                        extentIntersect = extentIntersect.intersection(dataStoreList[i].getExtent());
209
                                nRectangles ++;
210
                        }
211
                }
212
                Rectangle2D[] result = new Rectangle2D[nRectangles];
213
                
214
                Point2D p1 = new Point2D.Double(extentIntersect.getULX(), extentIntersect.getULY());
215
                Point2D p2 = new Point2D.Double(extentIntersect.getLRX(), extentIntersect.getLRY());
216
                
217
                int cont = 0;
218
                for (int i = 0; i < dataStoreList.length; i++) {
219
                        if(dataStoreList[i] != null) {
220
                                Point2D init = dataStoreList[i].worldToRaster(p1);
221
                                Point2D end = dataStoreList[i].worldToRaster(p2);
222
                                result[cont] = new Rectangle2D.Double(
223
                                                init.getX(), 
224
                                                init.getY(), 
225
                                                Math.abs(end.getX() - init.getX()), 
226
                                                Math.abs(end.getY() - init.getY()));
227
                                cont++;
228
                        }
229
                }
230
                return result;
231
        }
232
        
233
        /**
234
         * Checks if the point in pixel coordinates is inside the region of 
235
         * interest or not. The point will be
236
         * @param x 
237
         * @param y
238
         * @param rois
239
         * @param extentResult
240
         *       Bounding box of the area to which belongs the point defined in pixel coordinates (x, y)
241
         * @return
242
         */
243
        public boolean isInsideOfROI(int x, int y, List<ROI> rois, Extent extentResult) {
244
                if(rois == null || rois.size() == 0)
245
                        return true;
246
                
247
                ROI roi = rois.get(0);
248
                int[] shift = getROIAnalysisShift(extentResult, roi.getStore().getExtent(), roi.getStore().getCellSize());
249
                
250
                for (int i = 0; i < rois.size(); i++) {
251
                        if(rois.get(i).isInsideOfPolygon(x + shift[0], y + shift[1]))
252
                                return true;
253
                }
254
                return false;
255
        }
256
        
257
        /**
258
         * Gets the shift in pixels between the source bounding box and the result bounding box.
259
         * This is useful to get if a pixel is inside a region of interest because the ROI has 
260
         * associate the source. 
261
         * @param extentResult
262
         * @param sourceExtent
263
         * @return
264
         */
265
        private int[] getROIAnalysisShift(Extent extentResult, Extent sourceExtent, double cellsize) {
266
                double xDistance = Math.abs(extentResult.getULX() - sourceExtent.getULX());
267
                double yDistance = Math.abs(extentResult.getULY() - sourceExtent.getULY());
268
                return new int[]{(int)(xDistance / cellsize), (int)(yDistance / cellsize)};
269
        }
270
        
271
        /**
272
         * Gets the bounding box taking into account whether there are ROIs or not
273
         * @return
274
         */
275
        public Extent getExtentResult(List<ROI> rois, RasterDataStore store) {
276
                if(rois == null)
277
                        return store.getExtent();
278
                else {
279
                        Extent maxExtent = null;
280
                        for (int i = 0; i < rois.size(); i++) {
281
                                if(i == 0)
282
                                        maxExtent = rois.get(i).getROIExtent();
283
                                else
284
                                        maxExtent = maxExtent.encloseBoundinBoxes(rois.get(i).getROIExtent());
285
                        }
286
                        return maxExtent.intersection(store.getExtent());
287
                }
288
        }
289
        
290
        /**
291
         * Gets the bounding box of the source in pixel coordinates
292
         * @param resultExtent
293
         * @return
294
         */
295
        public Rectangle2D getSourcePxBox(Extent resultExtent, RasterDataStore store) {
296
                if(resultExtent == null || resultExtent.equals(store.getExtent()))
297
                        return new Rectangle2D.Double(0, 0, store.getWidth(), store.getHeight());
298
                Point2D p1 = store.worldToRaster(new Point2D.Double(resultExtent.getULX(), resultExtent.getULY()));
299
                Point2D p2 = store.worldToRaster(new Point2D.Double(resultExtent.getLRX(), resultExtent.getLRY()));
300
                return new Rectangle2D.Double(p1.getX(), p1.getY(), Math.abs(p2.getX() - p1.getX()), Math.abs(p2.getY() - p1.getY()));
301
        }
302
        
303
        /**
304
         * Builds the output buffer
305
         * @param sourcePxBBox
306
         * @param bandCount
307
         * @return
308
         */
309
        public Buffer createOutputBuffer(int w, int h, int bandCount) {
310
                return createOutputBuffer(w, h, bandCount, Buffer.TYPE_DOUBLE);
311
        }
312
        
313
        public Buffer createOutputBuffer(int w, int h, int bandCount, int datatype) {
314
                RasterManager rManager = RasterLocator.getManager();
315
                BufferParam bParams = rManager.getBufferFactory().createBufferParams(
316
                                w, 
317
                                h, 
318
                                bandCount, 
319
                                datatype, 
320
                                true);
321
                Buffer resultBuffer = null;
322
                try {
323
                        resultBuffer = rManager.getBufferFactory().createBuffer(bParams);
324
                } catch (BufferCreationException e) {
325
                        new ProcessException("Error creating the output buffer", e);
326
                }
327
                return resultBuffer;
328
        }
329
        
330
        /**
331
         * Gets a data buffer from a <code>RasterDataStore</code> 
332
     */
333
    public Buffer createSourceBuffer(RasterDataStore store, Rectangle2D sourcePxBBox, boolean[] bands) throws ProcessException {
334
        RasterManager rManager = RasterLocator.getManager();
335
        RasterQuery query = rManager.createQuery();
336
        query.setReadOnly(true);
337
        
338
        int nBands = getNumberOfSelectedBands(bands);
339
        int count = 0;
340
        int[] drawableBands = new int[nBands];
341
        for (int i = 0; i < bands.length; i++) {
342
                        if(bands[i]) {
343
                                drawableBands[count] = i;
344
                                count ++;
345
                        }
346
                }
347
        
348
        query.setDrawableBands(drawableBands);
349
        query.setAreaOfInterest(
350
                        (int)sourcePxBBox.getX(), 
351
                        (int)sourcePxBBox.getY(), 
352
                        (int)sourcePxBBox.getWidth(), 
353
                        (int)sourcePxBBox.getHeight());
354

    
355
        try {
356
                Buffer buffer = null;
357
                try {
358
                        buffer = store.query(query);
359
                } catch (RasterDriverException e) {
360
                        new ProcessException("Error creating the input buffer", e);
361
                }  catch (InvalidSetViewException e) {
362
                        new ProcessException("Error creating the input buffer", e);
363
                } 
364
                return buffer;
365
        } catch (ProcessInterruptedException e) {
366
        }
367
        return null;
368
    } 
369
    
370
        /**
371
         * Gets the number of the selected bands from a list of boolean values.
372
         * Each element in this list represents a band and true or false if the band
373
         * will be used in the task.
374
         * @param bandsPCs
375
         * @return
376
         */
377
        private int getNumberOfSelectedBands(boolean[] b) {
378
                int bandCount = 0;
379
        for (int i = 0; i < b.length; i++) {
380
                        if(b[i])
381
                                bandCount++;
382
                }
383
        return bandCount;
384
        }
385
        
386
        /**
387
         * Gets a value of the buffer in double format
388
         * @param b
389
         * @param row
390
         * @param col
391
         * @param band
392
         * @return
393
         */
394
        protected double getData(Buffer b, int row, int col, int band) {
395
                if(b.getDataType() == Buffer.TYPE_BYTE) {
396
                        return (double)b.getElemByte(row, col, band);
397
                }
398
                if(b.getDataType() == Buffer.TYPE_DOUBLE) {
399
                        return b.getElemDouble(row, col, band);
400
                }
401
                if(b.getDataType() == Buffer.TYPE_FLOAT) {
402
                        return (double)b.getElemFloat(row, col, band);
403
                }
404
                if(b.getDataType() == Buffer.TYPE_INT) {
405
                        return (double)b.getElemInt(row, col, band);
406
                }
407
                if(b.getDataType() == Buffer.TYPE_SHORT) {
408
                        return (double)b.getElemShort(row, col, band);
409
                }
410
                NoData nd = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE);
411
                return nd.getValue().doubleValue();
412
        }
413
}