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 @ 2130

History | View | Annotate | Download (15.4 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.store.DataServerWriter;
45
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
46
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
47
import org.gvsig.fmap.dal.coverage.store.RasterWriter;
48
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
49
import org.gvsig.fmap.dal.exception.InitializeException;
50
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
51
import org.gvsig.i18n.Messages;
52
import org.gvsig.raster.roi.ROI;
53
import org.slf4j.LoggerFactory;
54
/**
55
 * Clase base de todos los procesos raster. En ella se genstionan todas las
56
 * funciones comunes como incremento de la tarea, gesti?n de eventos a la tarea, 
57
 * par?metros de la tarea, etc ...
58
 * 
59
 * 18/12/2007
60
 * @author Nacho Brodin nachobrodin@gmail.com
61
 */
62
public abstract class ProcessUtils {
63
        protected NoData        doubleNODATA = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE);
64
        
65
        /**
66
         * Registra un mensaje de error en el log de gvSIG
67
         * @param msg Mensaje a guardar en el log
68
         * @param parent Objeto que hizo disparar el mensaje
69
         * @param exception Excepcion que ha sido recogida
70
         */
71
        public void debug(String msg, Object parent, Exception exception) {
72
                if(parent != null)
73
                    LoggerFactory
74
            .getLogger(parent.getClass()).debug(Messages.getText(msg), exception);
75
        }
76
        
77
        /**
78
         * Shows a error dialog with a text and a accept button 
79
         * @param msg Message to show in the dialog
80
         * @param parentWindow Parent window
81
         */
82
        public void messageBoxError(String msg, Object parentWindow){
83
                String string = Messages.getText("accept");
84
                Object[] options = {string};
85
                JOptionPane.showOptionDialog((Component)parentWindow,
86
                                        "<html>" + Messages.getText(msg).replaceAll("\n", "<br>") + "</html>",
87
                                        Messages.getText("confirmacion"),
88
                                        JOptionPane.OK_OPTION,
89
                                        JOptionPane.ERROR_MESSAGE,
90
                                        null,
91
                                        options,
92
                                        string);
93
        }
94
        
95
        /**
96
         * Muestra un dialogo de error con un texto y un bot?n de aceptar. El error es
97
         * registrado en el log de gvSIG con la excepcion que se le pase por parametro
98
         * @param msg Mensaje a mostrar en el dialogo.
99
         * @param parentWindow Ventana desde la que se lanza el dialogo
100
         * @param exception Excepcion que ha sido recogida
101
         */
102
        public void messageBoxError(String msg, Object parentWindow, Exception exception) {
103
                debug(msg, parentWindow, exception);
104
                messageBoxError(msg, parentWindow);
105
        }
106
        
107
        /**
108
         * Muestra un dialogo de error con un texto y un bot?n de aceptar. Se le pasa como ?ltimo par?metros
109
         * una lista de excepciones que ser?n guardadas en el log
110
         * @param msg Mensaje a mostrar en el dialogo.
111
         * @param parentWindow Ventana desde la que se lanza el dialogo
112
         * @param exception Excepcion que ha sido recogida
113
         */
114
        public void messageBoxError(String msg, Object parentWindow, ArrayList<Exception> exception) {
115
                for (int i = 0; i < exception.size(); i++) 
116
                        debug(msg, parentWindow, exception.get(i));
117
                messageBoxError(msg, parentWindow);
118
        }
119
        
120
        /**
121
         * Exports a raster buffer to disk
122
         * @param sFilename
123
         * @param buf
124
         * @param cellsize
125
         * @param minX
126
         * @param minY
127
         * @return
128
         * @throws ProviderNotRegisteredException 
129
         * @throws InitializeException 
130
         */
131
        public boolean exportRaster(final String sFilename, 
132
                        Buffer buf, 
133
                        double cellsize, 
134
                        double minX, 
135
                        double minY,
136
                        NoData nodata) {
137
                boolean result = exportRaster(sFilename, buf, cellsize, minX, minY);
138
                nodata.setFileName(sFilename);
139
                nodata.save();
140
                return result;
141
                /*DataManager manager = DALLocator.getDataManager();
142
                String provider = "Gdal Store";
143
                DataServerExplorerParameters eparams = manager.createServerExplorerParameters("FilesystemExplorer");
144
                
145
                DataServerExplorer serverExplorer = manager.openServerExplorer(eparams.getExplorerName(), eparams);
146

147
                NewRasterStoreParameters sparams = (NewRasterStoreParameters)serverExplorer.getAddParameters(provider);
148
                sparams.setDataServer((DataServerWriter)processIncrement);
149
                sparams.setDestination(path, file);
150
                sparams.setBuffer(buffer);
151
                sparams.setColorInterpretation(new String[]{ColorInterpretation.GRAY_BAND});
152
                sparams.setWktProjection(dstoreCopy.getWktProjection());
153
                sparams.setBand(i);
154
                sparams.setAffineTransform(affineTransform);
155
                sparams.setDriverParams(params);*/
156
        }
157
        
158
        /**
159
         * Exports a raster buffer to disk
160
         * @param sFilename
161
         * @param buf
162
         * @param cellsize
163
         * @param minX
164
         * @param minY
165
         * @return
166
         */
167
        @SuppressWarnings("deprecation")
168
        public boolean exportRaster(final String sFilename, 
169
                        Buffer buf, 
170
                        Buffer alphaBuffer, 
171
                        double cellsize, 
172
                        double minX, 
173
                        double minY) {
174
                try {
175
                        RasterManager manager = RasterLocator.getManager();
176
                        final DataServerWriter writerBufferServer = manager.createDataServerWriter();
177
                        writerBufferServer.setBuffer(buf, -1);
178
                        int nBands = buf.getBandCount();
179
                        ColorInterpretation colorInterpretation = null;
180
                        if(alphaBuffer != null) {
181
                                writerBufferServer.setAlphaBuffer(alphaBuffer);
182
                                nBands ++;
183
                                colorInterpretation = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(
184
                                                new String[] { 
185
                                                                ColorInterpretation.RED_BAND, 
186
                                                                ColorInterpretation.GREEN_BAND, 
187
                                                                ColorInterpretation.BLUE_BAND,
188
                                                                ColorInterpretation.ALPHA_BAND});
189
                        } else {
190
                                if(nBands == 1)
191
                                        colorInterpretation = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(
192
                                                        new String[] { ColorInterpretation.GRAY_BAND });
193
                        }
194
                        final Params params = manager.createWriterParams(sFilename);
195
                        final AffineTransform affineTransform =
196
                                new AffineTransform(cellsize, 0, 0,
197
                                                -cellsize, minX, minY);
198

    
199
                        final RasterWriter writer = manager.createWriter(
200
                                                writerBufferServer, 
201
                                                sFilename,
202
                                                nBands, 
203
                                                affineTransform, 
204
                                                buf.getWidth(),
205
                                                buf.getHeight(), 
206
                                                buf.getDataType(), 
207
                                                params, 
208
                                                null);
209
                        if(colorInterpretation != null)
210
                                writer.setColorBandsInterpretation(colorInterpretation.getValues());
211
                        writer.dataWrite();
212
                        writer.writeClose();
213
                } catch (final Exception e) {
214
                        e.printStackTrace();
215
                        return false;
216
                }
217
                return true;
218
        }
219
        
220
        /**
221
         * Exports a raster buffer to disk
222
         * @param sFilename
223
         * @param buf
224
         * @param cellsize
225
         * @param minX
226
         * @param minY
227
         * @return
228
         */
229
        public boolean exportRaster(final String sFilename, 
230
                        Buffer buf, 
231
                        double cellsize, 
232
                        double minX, 
233
                        double minY) {
234
        return exportRaster(sFilename, buf, null, cellsize, minX, minY);
235
    }
236
        
237
        /**
238
         * Gets a list of rectangles which represents the pixel coordinates of each DataStore.
239
         * This rectangle is the area that intersects with the other DataStores in the         list.
240
         * @param dataStoreList
241
         * @return
242
         */
243
        protected Rectangle2D[] getIntersectionInPxCoords(RasterDataStore[] dataStoreList) {
244
                Extent extentIntersect = null;
245
                int nRectangles = 0;
246
                for (int i = 0; i < dataStoreList.length; i++) {
247
                        if(dataStoreList[i] != null) {
248
                                if(extentIntersect == null)
249
                                        extentIntersect = dataStoreList[i].getExtent();
250
                                else
251
                                        extentIntersect = extentIntersect.intersection(dataStoreList[i].getExtent());
252
                                nRectangles ++;
253
                        }
254
                }
255
                Rectangle2D[] result = new Rectangle2D[nRectangles];
256
                
257
                Point2D p1 = new Point2D.Double(extentIntersect.getULX(), extentIntersect.getULY());
258
                Point2D p2 = new Point2D.Double(extentIntersect.getLRX(), extentIntersect.getLRY());
259
                
260
                int cont = 0;
261
                for (int i = 0; i < dataStoreList.length; i++) {
262
                        if(dataStoreList[i] != null) {
263
                                Point2D init = dataStoreList[i].worldToRaster(p1);
264
                                Point2D end = dataStoreList[i].worldToRaster(p2);
265
                                result[cont] = new Rectangle2D.Double(
266
                                                init.getX(), 
267
                                                init.getY(), 
268
                                                Math.abs(end.getX() - init.getX()), 
269
                                                Math.abs(end.getY() - init.getY()));
270
                                cont++;
271
                        }
272
                }
273
                return result;
274
        }
275
        
276
        /**
277
         * Checks if the point in pixel coordinates is inside the region of 
278
         * interest or not. The point will be
279
         * @param x 
280
         * @param y
281
         * @param rois
282
         * @param extentResult
283
         *       Bounding box of the area to which belongs the point defined in pixel coordinates (x, y)
284
         * @return
285
         */
286
        public boolean isInsideOfROI(int x, int y, List<ROI> rois, Extent extentResult) {
287
                if(rois == null || rois.size() == 0)
288
                        return true;
289
                
290
                ROI roi = rois.get(0);
291
                int[] shift = getROIAnalysisShift(extentResult, roi.getStore().getExtent(), roi.getStore().getCellSize());
292
                
293
                for (int i = 0; i < rois.size(); i++) {
294
                        if(rois.get(i).isInsideOfPolygon(x + shift[0], y + shift[1]))
295
                                return true;
296
                }
297
                return false;
298
        }
299
        
300
        /**
301
         * Gets the shift in pixels between the source bounding box and the result bounding box.
302
         * This is useful to get if a pixel is inside a region of interest because the ROI has 
303
         * associate the source. 
304
         * @param extentResult
305
         * @param sourceExtent
306
         * @return
307
         */
308
        private int[] getROIAnalysisShift(Extent extentResult, Extent sourceExtent, double cellsize) {
309
                double xDistance = Math.abs(extentResult.getULX() - sourceExtent.getULX());
310
                double yDistance = Math.abs(extentResult.getULY() - sourceExtent.getULY());
311
                return new int[]{(int)(xDistance / cellsize), (int)(yDistance / cellsize)};
312
        }
313
        
314
        /**
315
         * Gets the bounding box taking into account whether there are ROIs or not
316
         * @return
317
         */
318
        public Extent getExtentResult(Extent window, List<ROI> rois, RasterDataStore store) {
319
                if(window != null)
320
                        return window.intersection(store.getExtent());
321
                if(rois == null)
322
                        return store.getExtent();
323
                else {
324
                        Extent maxExtent = null;
325
                        for (int i = 0; i < rois.size(); i++) {
326
                                if(i == 0)
327
                                        maxExtent = rois.get(i).getROIExtent();
328
                                else
329
                                        maxExtent = maxExtent.encloseBoundinBoxes(rois.get(i).getROIExtent());
330
                        }
331
                        return maxExtent.intersection(store.getExtent());
332
                }
333
        }
334
        
335
        /**
336
         * Returns true if the algorithm is applied to the entire layer
337
         * @param extent
338
         * @param rois
339
         * @param store
340
         * @return
341
         */
342
        public boolean isAnalizedEntireLayer(Extent window, List<ROI> rois, RasterDataStore store) {
343
                if(window == null) {
344
                        if(rois == null || rois.size() == 0)
345
                                return true;
346
                }
347
                return false;
348
        }
349
        
350
        /**
351
         * Gets the bounding box of the source in pixel coordinates
352
         * @param resultExtent
353
         * @return
354
         */
355
        public Rectangle2D getSourcePxBox(Extent resultExtent, RasterDataStore store) {
356
                if(resultExtent == null || resultExtent.equals(store.getExtent()))
357
                        return new Rectangle2D.Double(0, 0, store.getWidth(), store.getHeight());
358
                Point2D p1 = store.worldToRaster(new Point2D.Double(resultExtent.getULX(), resultExtent.getULY()));
359
                Point2D p2 = store.worldToRaster(new Point2D.Double(resultExtent.getLRX(), resultExtent.getLRY()));
360
                return new Rectangle2D.Double(p1.getX(), p1.getY(), Math.abs(p2.getX() - p1.getX()), Math.abs(p2.getY() - p1.getY()));
361
        }
362
        
363
        /**
364
         * Builds the output buffer
365
         * @param sourcePxBBox
366
         * @param bandCount
367
         * @return
368
         */
369
        public Buffer createOutputBuffer(int w, int h, int bandCount) {
370
                return createOutputBuffer(w, h, bandCount, Buffer.TYPE_DOUBLE);
371
        }
372
        
373
        public Buffer createOutputBuffer(int w, int h, int bandCount, int datatype) {
374
                RasterManager rManager = RasterLocator.getManager();
375
                BufferParam bParams = rManager.getBufferFactory().createBufferParams(
376
                                w, 
377
                                h, 
378
                                bandCount, 
379
                                datatype, 
380
                                true);
381
                Buffer resultBuffer = null;
382
                try {
383
                        resultBuffer = rManager.getBufferFactory().createBuffer(bParams);
384
                } catch (BufferCreationException e) {
385
                        new ProcessException("Error creating the output buffer", e);
386
                }
387
                return resultBuffer;
388
        }
389
        
390
        /**
391
         * Gets a data buffer from a <code>RasterDataStore</code> 
392
     */
393
    public Buffer createSourceBuffer(RasterDataStore store, Rectangle2D sourcePxBBox, boolean[] bands) throws ProcessException {
394
        RasterManager rManager = RasterLocator.getManager();
395
        RasterQuery query = rManager.createQuery();
396
        query.setReadOnly(true);
397
        
398
        int nBands = getNumberOfSelectedBands(bands);
399
        int count = 0;
400
        int[] drawableBands = new int[nBands];
401
        for (int i = 0; i < bands.length; i++) {
402
                        if(bands[i]) {
403
                                drawableBands[count] = i;
404
                                count ++;
405
                        }
406
                }
407
        
408
        query.setDrawableBands(drawableBands);
409
        query.setAreaOfInterest(
410
                        (int)sourcePxBBox.getX(), 
411
                        (int)sourcePxBBox.getY(), 
412
                        (int)sourcePxBBox.getWidth(), 
413
                        (int)sourcePxBBox.getHeight());
414

    
415
        try {
416
                Buffer buffer = null;
417
                try {
418
                        buffer = store.query(query);
419
                } catch (RasterDriverException e) {
420
                        new ProcessException("Error creating the input buffer", e);
421
                }  catch (InvalidSetViewException e) {
422
                        new ProcessException("Error creating the input buffer", e);
423
                } 
424
                return buffer;
425
        } catch (ProcessInterruptedException e) {
426
        }
427
        return null;
428
    } 
429
    
430
        /**
431
         * Gets the number of the selected bands from a list of boolean values.
432
         * Each element in this list represents a band and true or false if the band
433
         * will be used in the task.
434
         * @param bandsPCs
435
         * @return
436
         */
437
        private int getNumberOfSelectedBands(boolean[] b) {
438
                int bandCount = 0;
439
        for (int i = 0; i < b.length; i++) {
440
                        if(b[i])
441
                                bandCount++;
442
                }
443
        return bandCount;
444
        }
445
        
446
        /**
447
         * Gets a value of the buffer in double format
448
         * @param b
449
         * @param row
450
         * @param col
451
         * @param band
452
         * @return
453
         */
454
        protected double getData(Buffer b, int row, int col, int band) {
455
                if(b.getDataType() == Buffer.TYPE_BYTE) {
456
                        return (double)b.getElemByte(row, col, band);
457
                }
458
                if(b.getDataType() == Buffer.TYPE_DOUBLE) {
459
                        return b.getElemDouble(row, col, band);
460
                }
461
                if(b.getDataType() == Buffer.TYPE_FLOAT) {
462
                        return (double)b.getElemFloat(row, col, band);
463
                }
464
                if(b.getDataType() == Buffer.TYPE_INT) {
465
                        return (double)b.getElemInt(row, col, band);
466
                }
467
                if(b.getDataType() == Buffer.TYPE_SHORT) {
468
                        return (double)b.getElemShort(row, col, band);
469
                }
470
                
471
                return doubleNODATA.getValue().doubleValue();
472
        }
473
}