Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.algorithm / org.gvsig.raster.tools.algorithm.maskthreshold / src / main / java / org / gvsig / raster / tools / algorithm / maskthreshold / MaskthresholdProcess.java @ 1321

History | View | Annotate | Download (28.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.tools.algorithm.maskthreshold;
23

    
24
import java.awt.geom.Rectangle2D;
25
import java.util.HashMap;
26

    
27
import javax.swing.SwingUtilities;
28

    
29
import org.gvsig.fmap.dal.coverage.RasterLocator;
30
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
31
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
32
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
33
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
34
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
35
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
36
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
37
import org.gvsig.i18n.Messages;
38
import org.gvsig.raster.tools.algorithm.base.RasterBaseAlgorithmLibrary;
39
import org.gvsig.raster.tools.algorithm.base.process.ProcessException;
40
import org.gvsig.raster.tools.algorithm.base.process.RasterProcess;
41
import org.gvsig.raster.tools.algorithm.base.util.Operation;
42

    
43
/**
44
 * Process to create a mask using a threshold. This threshold could be a value
45
 * of a pixel or a fixed value.
46
 * 
47
 * Possible use cases:
48
 * <UL>
49
 * <LI><b>Fixed-oplayer:</b>  A input layer, an operator layer and a fixed value if the condition is satisfied.
50
 * If the condition is not satisfied the value is set to NoData</LI>
51
 * 
52
 * <LI><b>Fixed-threshold:</b>  A input layer, a threshold and a fixed value if the condition is satisfied.
53
 * If the condition is not satisfied the value is set to NoData</LI>
54
 *
55
 * <LI><b>Replicate-oplayer:</b>  A input layer, an operator layer and a output layer. If the condition is satisfied.
56
 * the result layer replicates the output bands. If the condition is not satisfied the values is set to NoData</LI>
57
 * 
58
 * <LI><b>Replicate-threshold:</b>  A input layer, a threshold layer and a output layer. If the condition is satisfied.
59
 * the result layer replicates the output bands. If the condition is not satisfied the values is set to NoData</LI>
60
 * 
61
 * <LI><b>Transparent-oplayer:</b> A input layer, an operator layer and a RGB output layer. If the condition is satisfied
62
 * the layer result replicates the output RGB with transparency values. If the condition is not satisfied 
63
 * the layer result only replicates the output RGB.</LI>
64
 * 
65
 * <LI><b>Transparent-threshold:</b> A input layer, a threshold and a RGB output layer. If the condition is satisfied
66
 * the layer result replicates the output RGB with transparency values. If the condition is not satisfied 
67
 * the layer result only replicates the output RGB.</LI>
68
 * 
69
 * <LI><b>Opacity-oplayer:</b> A input layer, an operator layer, a RGB output layer. If the condition is satisfied
70
 * the layer result replicates the output layer values and if not this pixels are set to transparent </LI>
71
 * 
72
 * <LI><b>Opacity-threshold:</b> A input layer, an operator layer, a threshold. If the condition is satisfied
73
 * the layer result replicates the output layer values and if not this pixels are set to transparent </LI>
74
 * </UL>
75
 * 
76
 * <table>
77
 * <tr>
78
 * <th>band1</th><th>band2</th><th>threshold</th><th>output</th>
79
 * </tr>
80
 * <tr>
81
 * <td>-1</td><td>-1</td><td>-</td><td>el n?mero de bandas de la capa de operaci?n debe 
82
 *                                   ser mayor o igual a la de entrada. Compara la banda 
83
 *                                   i de la capa de entrada con la banda i de la de operaci?n</td>
84
 * </tr>
85
 * <tr>
86
 * <td>-1</td><td>0</td><td>-</td><td>Compara todas las bandas de la capa de entrada con la 
87
 *                                   banda cero de la capa de operaci?n</td>
88
 * </tr>
89
 * <tr>
90
 * <td>-1</td><td>-</td><td>value</td><td>Compara todas las bandas de la capa de entrada con el valor 
91
 *                                   de threshold</td>
92
 * </tr>
93
 * <tr>
94
 * <td>0</td><td>-1</td><td>-</td><td>Caso no permitido</td>
95
 * </tr>
96
 * <tr>
97
 * <td>0</td><td>-</td><td>value</td><td>Compara la banda cero de la capa de entrada con el valor
98
 *                                   de threshold</td>
99
 * </tr>                                  
100
 * </table>  
101
 * 
102
 * Input parameters
103
 * <UL>
104
 * <LI><b>RASTER_STORE1:</b>(Store method) Input store.</LI>
105
 * <LI><b>RASTER_STORE2:</b>(Store method) Operation store. If this parameter is null then THRESHOLD is mandatory</LI>
106
 * <LI><b>RASTER_STORE3:</b>(Store method) Output store. If this parameter is null then FIXED_VALUE is mandatory</LI>
107
 * <LI><b>RASTER_BUFFER1:</b>(Buffer method) Input buffer</LI>
108
 * <LI><b>RASTER_BUFFER2:</b>(Buffer method) Operation buffer. If this parameter is null then THRESHOLD is mandatory</LI>
109
 * <LI><b>RASTER_BUFFER3:</b>(Buffer method) Output buffer. If this parameter is null then FIXED_VALUE is mandatory</LI>
110
 * <LI><b>BAND1:</b> RASTER_STORE1 band. Band to compare with the threshold or operation band. If BAND1 is lesser than 0 then all
111
 * bands will be compared. If BAND1 is lesser than zero and BAND2 is lesser than zero then the store </LI>
112
 * <LI><b>BAND2:</b> RASTER_STORE2 band. Band to compare with the input store band</LI>
113
 * <LI><b>BAND3:</b> RASTER:STORE3 band. Band to put in the output when the method is "layer bands selecteds"</LI>
114
 * <LI><b>THRESHOLD:</b> Threshold to compare with the input data</LI>
115
 * <LI><b>FIXED_VALUE:</b> Value to put in the output when the method is "Fixed Value" or "NoData"</LI>
116
 * <LI><b>OPERATION:</b> Operation. Index in list MASK_OPERATIONS</LI>
117
 * <LI><b>SATISFY_METHOD:</b> Output method. Index in list OUTPUT_METHODS</LI>
118
 * <LI><b>PATH:</b></LI>
119
 * </UL>
120
 * 
121
 * Possible output parameters
122
 * <UL>
123
 * <LI><b>BUFFER:</b></LI>
124
 * <LI><b>FILENAME:</b></LI>
125
 * <LI><b>TIME:</b></LI>
126
 * </UL>
127
 * 10/12/2007
128
 * @author Nacho Brodin nachobrodin@gmail.com
129
 */
130
public class MaskthresholdProcess extends RasterProcess {
131
        //Possible input parameters
132
        public static String      RASTER_STORE1    = "RasterStore1"; //Input store
133
        public static String      RASTER_STORE2    = "RasterStore2"; //Operation store if exists (threshold)
134
        public static String      RASTER_STORE3    = "RasterStore3"; //Output store if exists (fixed value)
135
        public static String      RASTER_BUFFER1   = "Buffer1";      //Intput buffer
136
        public static String      RASTER_BUFFER2   = "Buffer2";      //Operation buffer if exists (threshold)
137
        public static String      RASTER_BUFFER3   = "Buffer3";      //Output buffer if exists (fixed value)
138
        public static String      BAND1            = "Band1";       
139
        public static String      BAND2            = "Band2";
140
        public static String      BAND3            = "Band3";
141
        public static String      THRESHOLD        = "Threshold";
142
        public static String      FIXED_VALUE      = "FixedValue";
143
        public static String      OPERATION        = "Operation";
144
        public static String      SATISFY_METHOD   = "Satisfy_Method";
145
        public static String      PATH             = "Path";
146
        
147
        //Possible output parameters
148
        public static String      BUFFER           = "Buffer";
149
        public static String      FILENAME         = "FileName";
150
        public static String      TIME             = "Time";
151
        
152
        public static String[]    MASK_OPERATIONS  = new String[]{"Greater", "Lower", 
153
                                                                      "GreaterOrEquals", "LoweOrEquals"};
154
        public static String[]    OUTPUT_METHODS   = new String[]{"NoData", "FixedValue", 
155
                                                                      "Transparency", "Opacity", 
156
                                                                      "LayerAndBandsSelected", "LayerAndBandsSelectedInverse"};
157
        
158
        private RasterDataStore   inputStore       = null;
159
        private RasterDataStore   operationStore   = null;
160
        private RasterDataStore   outputStore      = null;
161
        private Buffer            inputBuffer      = null;
162
        private Buffer            operationBuffer  = null;
163
        private Buffer            outputBuffer     = null;
164
        private int               band1            = 0;
165
        private int               band2            = 0;
166
        private int               band3            = 0; //-1 All
167
        private int               resultNumBands   = 0;
168
        
169
        private String            filename         = null; //If is null only returns a buffer
170
        private double            threshold        = 0;
171
        private double            fixedValue       = 0;
172
        private NoData            nodata           = null;
173
        private AbstractOperation operation        = null;
174
        private AbstractOperation opSatisfy        = null;
175
        private AbstractOperation opNotSatisfy     = null;
176
        private long              milis            = 0;
177
        private int               percent          = 0;
178
        private Buffer            resultBuffer     = null;
179
        
180
        public static void registerParameters() {
181
                RASTER_STORE1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE1, RasterDataStore.class);
182
                RASTER_STORE2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE2, RasterDataStore.class);
183
                RASTER_STORE3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE3, RasterDataStore.class);
184
                
185
                RASTER_BUFFER1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER1, Buffer.class);
186
                RASTER_BUFFER2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER2, Buffer.class);
187
                RASTER_BUFFER3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER3, Buffer.class);
188
                
189
                BAND1 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND1, Integer.class);
190
                BAND2 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND2, Integer.class);
191
                BAND3 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND3, Integer.class);
192
                
193
                SATISFY_METHOD = RasterBaseAlgorithmLibrary.registerInputParameter(SATISFY_METHOD, Integer.class);
194
                THRESHOLD = RasterBaseAlgorithmLibrary.registerInputParameter(THRESHOLD, Double.class);
195
                FIXED_VALUE = RasterBaseAlgorithmLibrary.registerInputParameter(FIXED_VALUE, Double.class);
196
                OPERATION = RasterBaseAlgorithmLibrary.registerInputParameter(OPERATION, Integer.class);
197
                
198
                PATH = RasterBaseAlgorithmLibrary.registerInputParameter(PATH, String.class);
199
                
200
                FILENAME = RasterBaseAlgorithmLibrary.registerOutputParameter(FILENAME, String.class);
201
                BUFFER = RasterBaseAlgorithmLibrary.registerOutputParameter(BUFFER, Buffer.class);
202
                TIME = RasterBaseAlgorithmLibrary.registerOutputParameter(TIME, Long.class);
203
        }
204
        
205
        /*
206
         * (non-Javadoc)
207
         * @see org.gvsig.rastertools.RasterProcess#init()
208
         */
209
        public void init() {
210
                inputStore = getParam(RASTER_STORE1) != null ? (RasterDataStore)getParam(RASTER_STORE1) : null; //M
211
                operationStore = getParam(RASTER_STORE2) != null ? (RasterDataStore)getParam(RASTER_STORE2) : null; //Default Null
212
                outputStore = getParam(RASTER_STORE3) != null ? (RasterDataStore)getParam(RASTER_STORE3) : null; //Default Null
213
                
214
                inputBuffer = getParam(RASTER_BUFFER1) != null ? (Buffer)getParam(RASTER_BUFFER1) : null;
215
                operationBuffer = getParam(RASTER_BUFFER2) != null ? (Buffer)getParam(RASTER_BUFFER2) : null;
216
                outputBuffer = getParam(RASTER_BUFFER3) != null ? (Buffer)getParam(RASTER_BUFFER3) : null;
217
                
218
                band1 = (Integer)getIntParam(BAND1); //Default 0
219
                band2 = (Integer)getIntParam(BAND2); //Default 0
220
                band3 = (Integer)getIntParam(BAND3); //Default 0
221

    
222
                //Caso no permitido. No se puede comparar una banda de la de entrada 
223
                //con todas de la capa de operaci?n. Evitamos el pete
224
                if(band2 < 0 && band1 >= 0) 
225
                        band2 = 0;
226

    
227
                int satisfy = (Integer)getIntParam(SATISFY_METHOD); //Default 0
228

    
229
                if(satisfy == 0) {
230
                        opSatisfy = new NoDataOp();
231
                        opNotSatisfy = new FixedValueOp();
232
                        resultNumBands = 1;
233
                }
234
                if(satisfy == 1) {
235
                        opSatisfy = new FixedValueOp();
236
                        opNotSatisfy = new NoDataOp();
237
                        resultNumBands = 1;
238
                }
239
                if(satisfy == 2) {
240
                        opSatisfy = new TransparencyOp();
241
                        opNotSatisfy = new OpacityOp();
242
                        resultNumBands = 4;
243
                }
244
                if(satisfy == 3) {
245
                        opSatisfy = new OpacityOp();
246
                        opNotSatisfy = new TransparencyOp();
247
                        resultNumBands = 4;
248
                }
249
                if(satisfy == 4) {
250
                        opSatisfy = new LayerOp();
251
                        opNotSatisfy = new NoDataOp();
252
                }
253
                if(satisfy == 5) {
254
                        opSatisfy = new NoDataOp();
255
                        opNotSatisfy = new LayerOp();
256
                }
257
                if(satisfy == 4 || satisfy == 5) {
258
                        if(outputStore != null)
259
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputStore.getBandCount();
260
                        if(outputBuffer != null)
261
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputBuffer.getBandCount();
262
                }
263
                
264
                int op = (Integer)getIntParam(OPERATION); //Default 0
265
                if(op == 0)
266
                        operation = new Greater();
267
                if(op == 1)
268
                        operation = new Lower();
269
                if(op == 2)
270
                        operation = new GreaterOrEquals();
271
                if(op == 3)
272
                        operation = new LowerOrEquals();
273
                threshold = (Double)getDoubleParam(THRESHOLD); //Default 0
274
                fixedValue = (Double)getDoubleParam(FIXED_VALUE); //Default 0
275
                
276
                filename = getStringParam(PATH);
277
        }
278
        
279
        /**
280
         * M?todo donde se ejecutar? el Thread, aqu? se reproyecta el raster.
281
         */
282
        public void process() throws ProcessInterruptedException, ProcessException {
283
                long t1 = new java.util.Date().getTime();
284
                insertLineLog(Messages.getText("maskthreshold"));
285
                
286
                try {
287
                        if(inputStore != null)
288
                                checkStore();
289
                        else
290
                                checkBuffer();
291
                        
292
                        Rectangle2D[] pxBBox = null;
293
                        
294
                        if(inputStore != null) {
295
                                inputBuffer = readROBuffer(inputStore, band1);
296
                                RasterDataStore[] storeList = new RasterDataStore[]{inputStore, operationStore, outputStore};
297
                                pxBBox = getIntersectionInPxCoords(storeList);
298
                        } else {
299
                                Rectangle2D r = new Rectangle2D.Double(0, 0, inputBuffer.getWidth(), inputBuffer.getHeight());
300
                                pxBBox = new Rectangle2D[]{r, r, r};
301
                        }
302
                        
303
                        if(operationStore != null) 
304
                                operationBuffer = readROBuffer(operationStore, band2);
305
                        
306
                        int dataType = Buffer.TYPE_DOUBLE;
307
                        
308
                        if(outputStore != null) { 
309
                                outputBuffer = readROBuffer(outputStore, band3);
310
                                dataType = outputBuffer.getDataType();
311
                        }
312
                        
313
                        resultBuffer = RasterLocator.getManager().createBuffer(
314
                                        dataType, 
315
                                        (int)pxBBox[0].getWidth(), 
316
                                        (int)pxBBox[0].getHeight(), 
317
                                        resultNumBands, true);
318
                        
319
                        write(resultBuffer, pxBBox);
320
                        
321
                        if(filename != null)
322
                                exportRaster(filename, resultBuffer, inputStore.getCellSize(), 
323
                                                inputStore.getExtent().getULX(), inputStore.getExtent().getULY());
324

    
325
                        long t2 = new java.util.Date().getTime();
326
                        milis = t2 - t1;
327
                        
328
                        SwingUtilities.invokeLater(new Runnable() {
329
                                public void run() {
330
                                        if (externalActions != null) {
331
                                                HashMap<String, Object> map = new HashMap<String, Object>();
332
                                                map.put(FILENAME, filename);
333
                                                map.put(BUFFER, resultBuffer);
334
                                                map.put(TIME, new Long(milis));
335
                                                externalActions.end(map);
336
                                        }
337
                                }
338
                        });
339
                } catch (MaskthresholdException e) {
340
                        if (incrementableTask != null)
341
                                incrementableTask.processFinalize();
342
                        messageBoxError("error_processing_maskthreshold", null, e);
343
                } finally {
344
                        if (incrementableTask != null) {
345
                                incrementableTask.processFinalize();
346
                                setProgressActive(false);
347
                        }
348
                }
349
        }
350
        
351
        /**
352
         * Checks input parameters for DataStores
353
         * @throws MaskthresholdException
354
         */
355
        private void checkStore() throws MaskthresholdException {
356
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
357
                                (outputStore == null || outputStore.getBandCount() < 3 || outputStore.getDataType()[0] != Buffer.TYPE_BYTE)) {
358
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
359
                }
360

    
361
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
362
                                outputStore == null)
363
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
364

    
365
                if (inputStore == null)
366
                        throw new MaskthresholdException("Layer not valid");
367
                
368
                if(operationStore != null) {
369
                        if(!inputStore.getExtent().intersects(operationStore.getExtent()))
370
                                throw new MaskthresholdException("Extents don't intersect");
371
                        if(inputStore.getCellSize() != operationStore.getCellSize())
372
                                throw new MaskthresholdException("Cell sizes are not equal");
373
                        if(band1 < 0 && band2 < 0) { // Si se comparan todas las bandas, la capa dos debe tener m?s bandas que la uno o las mismas
374
                                if(outputStore.getBandCount() < inputStore.getBandCount())
375
                                        throw new MaskthresholdException("If exists operation layer and all bands have to be compared then the operation layer must have more or the same number of bands that the input layer.");
376
                        }
377
                }
378
        }
379
        
380
        /**
381
         * Checks input parameters for Buffers
382
         * @throws MaskthresholdException
383
         */
384
        private void checkBuffer() throws MaskthresholdException {
385
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
386
                                (outputBuffer == null || outputBuffer.getBandCount() < 3 || outputBuffer.getDataType() != Buffer.TYPE_BYTE)) {
387
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
388
                }
389

    
390
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
391
                                outputBuffer == null)
392
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
393

    
394
                if (inputBuffer == null)
395
                        throw new MaskthresholdException("Layer not valid");
396
                
397
                if(outputBuffer != null) {
398
                        if ((inputBuffer.getWidth() != outputBuffer.getWidth()) || 
399
                                        (inputBuffer.getHeight() != outputBuffer.getHeight()))
400
                                throw new MaskthresholdException("Buffer sizes not valid");
401
                        if(band1 < 0 && band2 < 0) { // Si se comparan todas las bandas, la capa dos debe tener m?s bandas que la uno o las mismas
402
                                if(outputBuffer.getBandCount() < inputBuffer.getBandCount())
403
                                        throw new MaskthresholdException("If exists operation layer and all bands have to be compared then the operation layer must have more or the same number of bands that the input layer.");
404
                        }
405
                }
406
        }
407
        
408
        /**
409
         * Reads a band of a buffer
410
         * @param store
411
         * @param band
412
         * @return
413
         * @throws MaskthresholdException
414
         * @throws ProcessInterruptedException
415
         */
416
        private Buffer readROBuffer(RasterDataStore store, int band) throws MaskthresholdException, ProcessInterruptedException {
417
                RasterQuery query = RasterLocator.getManager().createQuery();
418
                if(band >= 0 && band < store.getBandCount())
419
                        query.setDrawableBands(new int[]{band});
420
                else
421
                        query.setAllDrawableBands();
422
                query.setReadOnly(true);
423
                query.setAreaOfInterest();
424
                
425
                try {
426
                        return store.query(query);
427
                } catch (RasterDriverException e) {
428
                        throw new MaskthresholdException("Error reading input raster.");
429
                } catch (InvalidSetViewException e) {
430
                        throw new MaskthresholdException("Error reading input raster.");
431
                }
432
        }
433
        
434
        private void write(Buffer result, Rectangle2D[] pxBbox) {
435
                if(nodata == null)
436
                        nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, result.getDataType());
437
                int colSource = (int)pxBbox[0].getX();
438
                int rowSource = (int)pxBbox[0].getY();
439
                int colOperation = colSource;
440
                int rowOperation = rowSource;
441
                if(pxBbox.length > 1) {
442
                        colOperation = (int)pxBbox[1].getX();
443
                        rowOperation = (int)pxBbox[1].getY();
444
                }
445

    
446
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
447
                opSatisfy.result = opNotSatisfy.result = result;
448
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
449
                opSatisfy.band = opNotSatisfy.band = band3;
450
                
451
                int inputInitBand = band1 < 0 ? 0 : band1;
452
                int inputEndBand = band1 < 0 ? inputBuffer.getBandCount() : band1 + 1;
453

    
454
                for (int row = 0; row < result.getHeight(); row++) {
455
                        if(pxBbox.length > 1) {
456
                                colOperation = (int)pxBbox[1].getX();
457
                                colSource = (int)pxBbox[0].getX();
458
                        }
459
                        colSource = 0;
460
                        for (int col = 0; col < result.getWidth(); col++) {
461
                                boolean compare = true;
462
                                for (int iBands = inputInitBand; iBands < inputEndBand; iBands++) {
463
                                        double op1 = getValue(inputBuffer, rowSource, colSource, iBands);
464
                                        double op2 = getValue(operationBuffer, rowOperation, colOperation, getBandToCompare(operationBuffer, iBands));
465
                                        if(!operation.compare(op1, op2)) {
466
                                                compare = false;
467
                                                break;
468
                                        }
469
                                }
470
                                if(compare) {
471
                                        opSatisfy.row = row;
472
                                        opSatisfy.col = col;
473
                                        opSatisfy.invoke();
474
                                } else {
475
                                        opNotSatisfy.row = row;
476
                                        opNotSatisfy.col = col;
477
                                        opNotSatisfy.invoke();
478
                                }
479
                                colSource ++;
480
                                colOperation++;
481
                        }
482
                        rowSource ++;
483
                        rowOperation ++;
484
                        percent = (int)((row * 100) / result.getHeight());
485
                }
486
        }
487

    
488
        /**
489
         * Gets the band to operate. If the buffer is null then it does not 
490
         * matter and it returns zero.
491
         * @param buf
492
         * @param inputBand
493
         * @return
494
         */
495
        private int getBandToCompare(Buffer buf, int inputBand) {
496
                if(buf == null)
497
                        return 0;
498
                if(band2 < 0)
499
                        return inputBand;
500
                else
501
                        return band2;
502
        }
503

    
504
        /**
505
         * Gets the operation value in using a double value. If there is a operation data store then
506
         * returns the value of the pixel in this position else it returns a threshold value
507
         * @param operationBuffer
508
         * @param rowOperation
509
         * @param colOperation
510
         * @return
511
         */
512
        private double getValue(Buffer buf, int rowOperation, int colOperation, int band) {
513
                if(buf == null)
514
                        return threshold;
515
                if(buf.getDataType() == Buffer.TYPE_BYTE)
516
                        return buf.getElemByte(rowOperation, colOperation, band);
517
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
518
                        return buf.getElemFloat(rowOperation, colOperation, band);
519
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
520
                        return buf.getElemDouble(rowOperation, colOperation, band);
521
                if(buf.getDataType() == Buffer.TYPE_SHORT)
522
                        return buf.getElemShort(rowOperation, colOperation, band);
523
                if(buf.getDataType() == Buffer.TYPE_INT)
524
                        return buf.getElemInt(rowOperation, colOperation, band);
525
                return 0;
526
        }
527
        
528
        /*
529
         * (non-Javadoc)
530
         * @see org.gvsig.raster.tools.app.basic.raster.process.RasterProcess#getResult()
531
         */
532
        public Object getResult() {
533
                HashMap<String, Object> map = new HashMap<String, Object>();
534
                map.put(FILENAME, filename);
535
                map.put(BUFFER, resultBuffer);
536
                map.put(TIME, new Long(milis));
537
                return map;
538
        }
539

    
540
        /*
541
         * (non-Javadoc)
542
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
543
         */
544
        public int getPercent() {
545
                return percent;
546
        }
547

    
548
        /*
549
         * (non-Javadoc)
550
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
551
         */
552
        public String getTitle() {
553
                return Messages.getText("maskthreshold");
554
        }
555
        
556
        abstract class AbstractOperation implements Operation {
557
                public int       row          = 0;
558
                public int       col          = 0;
559
                public Buffer    result       = null;
560
                public double    fixedValue   = 0;
561
                public Buffer    outBuffer   = null;
562
                public int       band         = 0;
563
                
564
                public void invoke() {
565
                        
566
                }
567
                public boolean compare(double a, double b) {
568
                        return false;
569
                }
570
        }
571
        
572
        class LayerOp extends AbstractOperation {
573
                public void invoke() {
574
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
575
                                if(band < 0) {
576
                                        for (int i = 0; i < result.getBandCount(); i++) {
577
                                                byte vSource = outBuffer.getElemByte(row, col, i);
578
                                                result.setElem(row, col, i, vSource);
579
                                        }
580
                                } else {
581
                                        byte vSource = outBuffer.getElemByte(row, col, band);
582
                                        result.setElem(row, col, band, vSource);
583
                                }
584
                        } else if(result.getDataType() == Buffer.TYPE_FLOAT) {
585
                                if(band < 0) {
586
                                        for (int i = 0; i < result.getBandCount(); i++) {
587
                                                float vSource = outBuffer.getElemFloat(row, col, i);
588
                                                result.setElem(row, col, i, vSource);
589
                                        }
590
                                } else {
591
                                        float vSource = outBuffer.getElemFloat(row, col, band);
592
                                        result.setElem(row, col, band, vSource);
593
                                }
594
                        } else if(result.getDataType() == Buffer.TYPE_DOUBLE) {
595
                                if(band < 0) {
596
                                        for (int i = 0; i < result.getBandCount(); i++) {
597
                                                double vSource = outBuffer.getElemDouble(row, col, i);
598
                                                result.setElem(row, col, i, vSource);
599
                                        }
600
                                } else {
601
                                        double vSource = outBuffer.getElemDouble(row, col, band);
602
                                        result.setElem(row, col, band, vSource);
603
                                }
604
                        } else if(result.getDataType() == Buffer.TYPE_SHORT) {
605
                                if(band < 0) {
606
                                        for (int i = 0; i < result.getBandCount(); i++) {
607
                                                float vSource = outBuffer.getElemShort(row, col, i);
608
                                                result.setElem(row, col, i, vSource);
609
                                        }
610
                                } else {
611
                                        float vSource = outBuffer.getElemShort(row, col, band);
612
                                        result.setElem(row, col, band, vSource);
613
                                }
614
                        } else if(result.getDataType() == Buffer.TYPE_INT) {
615
                                if(band < 0) {
616
                                        for (int i = 0; i < result.getBandCount(); i++) {
617
                                                int vSource = outBuffer.getElemInt(row, col, i);
618
                                                result.setElem(row, col, i, vSource);
619
                                        }
620
                                } else {
621
                                        int vSource = outBuffer.getElemInt(row, col, band);
622
                                        result.setElem(row, col, band, vSource);
623
                                }
624
                        }
625
                }
626
        }
627
        
628
        class TransparencyOp extends AbstractOperation {
629
                public void invoke() {
630
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
631
                                for (int i = 0; i < 3; i++) {
632
                                        byte vSource = outBuffer.getElemByte(row, col, i);
633
                                        result.setElem(row, col, i, vSource);
634
                                }
635
                                result.setElem(row, col, 4, (byte)0);
636
                        }
637
                }
638
        }
639
        
640
        class OpacityOp extends AbstractOperation {
641
                public void invoke() {
642
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
643
                                for (int i = 0; i < 3; i++) {
644
                                        byte vSource = outBuffer.getElemByte(row, col, i);
645
                                        result.setElem(row, col, i, vSource);
646
                                }
647
                                result.setElem(row, col, 4, (byte)255);
648
                        }
649
                }
650
        }
651

    
652
        class FixedValueOp extends AbstractOperation {
653
                public void invoke() {
654
                        if(result.getDataType() == Buffer.TYPE_BYTE)
655
                                result.setElem(row, col, 0, (byte)fixedValue);
656
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
657
                                result.setElem(row, col, 0, (float)fixedValue);
658
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
659
                                result.setElem(row, col, 0, fixedValue);
660
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
661
                                result.setElem(row, col, 0, (short)fixedValue);
662
                        else if(result.getDataType() == Buffer.TYPE_INT)
663
                                result.setElem(row, col, 0, (int)fixedValue);
664
                }
665
        }
666
        
667
        class NoDataOp extends AbstractOperation {
668
                public void invoke() {
669
                        if(result.getDataType() == Buffer.TYPE_BYTE)
670
                                if(band < 0) {
671
                                        for (int i = 0; i < result.getBandCount(); i++) {
672
                                                result.setElem(row, col, i, nodata.getValue().byteValue());
673
                                        }
674
                                } else {
675
                                        result.setElem(row, col, band, nodata.getValue().byteValue());
676
                                }
677
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
678
                                if(band < 0) {
679
                                        for (int i = 0; i < result.getBandCount(); i++) {
680
                                                result.setElem(row, col, i, nodata.getValue().floatValue());
681
                                        }
682
                                } else {
683
                                        result.setElem(row, col, band, nodata.getValue().floatValue());
684
                                }
685
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
686
                                if(band < 0) {
687
                                        for (int i = 0; i < result.getBandCount(); i++) {
688
                                                result.setElem(row, col, i, nodata.getValue().doubleValue());
689
                                        }
690
                                } else {
691
                                        result.setElem(row, col, band, nodata.getValue().doubleValue());
692
                                }
693
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
694
                                if(band < 0) {
695
                                        for (int i = 0; i < result.getBandCount(); i++) {
696
                                                result.setElem(row, col, i, nodata.getValue().shortValue());
697
                                        }
698
                                } else {
699
                                        result.setElem(row, col, band, nodata.getValue().shortValue());
700
                                }
701
                        else if(result.getDataType() == Buffer.TYPE_INT)
702
                                if(band < 0) {
703
                                        for (int i = 0; i < result.getBandCount(); i++) {
704
                                                result.setElem(row, col, i, nodata.getValue().intValue());
705
                                        }
706
                                } else {
707
                                        result.setElem(row, col, band, nodata.getValue().intValue());
708
                                }
709
                }
710
        }
711

    
712
        class Greater extends AbstractOperation {
713
                public boolean compare(double a, double b) {
714
                        return a > b;
715
                }
716
        }
717

    
718
        class Lower extends AbstractOperation {
719
                public boolean compare(double a, double b) {
720
                        return a < b;
721
                }
722
        }
723

    
724
        class GreaterOrEquals extends AbstractOperation {
725
                public boolean compare(double a, double b) {
726
                        return a >= b;
727
                }
728
        }
729

    
730
        class LowerOrEquals extends AbstractOperation {
731
                public boolean compare(double a, double b) {
732
                        return a <= b;
733
                }
734
        }
735
}