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

History | View | Annotate | Download (27.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

    
26
import org.gvsig.fmap.dal.coverage.RasterLocator;
27
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
29
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
30
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
31
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
32
import org.gvsig.fmap.dal.coverage.exception.QueryException;
33
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
34
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
35
import org.gvsig.i18n.Messages;
36
import org.gvsig.raster.algorithm.process.DataProcess;
37
import org.gvsig.raster.algorithm.process.ProcessException;
38
import org.gvsig.raster.algorithm.util.Operation;
39
import org.gvsig.tools.locator.LocatorException;
40

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

    
212
                //Caso no permitido. No se puede comparar una banda de la de entrada 
213
                //con todas de la capa de operaci?n. Evitamos el pete
214
                if(band2 < 0 && band1 >= 0) 
215
                        band2 = 0;
216

    
217
                int satisfy = (Integer)getIntParam(SATISFY_METHOD); //Default 0
218

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

    
319
                        addOutputValue(FILENAME, filename);
320
                        addOutputValue(BUFFER, resultBuffer);
321
                } catch (MaskthresholdException e) {
322
                        if (incrementableTask != null)
323
                                incrementableTask.processFinalize();
324
                        messageBoxError("error_processing_maskthreshold", null, e);
325
                } catch (LocatorException e) {
326
                        messageBoxError("error_creating_buffer", null, e);
327
                } catch (BufferCreationException e) {
328
                        messageBoxError("error_creating_buffer", null, e);
329
                } finally {
330
                        if (incrementableTask != null) {
331
                                incrementableTask.processFinalize();
332
                                setProgressActive(false);
333
                        }
334
                }
335
        }
336
        
337
        /**
338
         * Checks input parameters for DataStores
339
         * @throws MaskthresholdException
340
         */
341
        private void checkStore() throws MaskthresholdException {
342
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
343
                                (outputStore == null || outputStore.getBandCount() < 3 || outputStore.getDataType()[0] != Buffer.TYPE_BYTE)) {
344
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
345
                }
346

    
347
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
348
                                outputStore == null)
349
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
350

    
351
                if (inputStore == null)
352
                        throw new MaskthresholdException("Layer not valid");
353
                
354
                if(operationStore != null) {
355
                        if(!inputStore.getExtent().intersects(operationStore.getExtent()))
356
                                throw new MaskthresholdException("Extents don't intersect");
357
                        if(inputStore.getCellSize() != operationStore.getCellSize())
358
                                throw new MaskthresholdException("Cell sizes are not equal");
359
                        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
360
                                if(operationStore.getBandCount() < inputStore.getBandCount())
361
                                        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.");
362
                        }
363
                }
364
        }
365
        
366
        /**
367
         * Checks input parameters for Buffers
368
         * @throws MaskthresholdException
369
         */
370
        private void checkBuffer() throws MaskthresholdException {
371
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
372
                                (outputBuffer == null || outputBuffer.getBandCount() < 3 || outputBuffer.getDataType() != Buffer.TYPE_BYTE)) {
373
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
374
                }
375

    
376
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
377
                                outputBuffer == null)
378
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
379

    
380
                if (inputBuffer == null)
381
                        throw new MaskthresholdException("Layer not valid");
382
                
383
                if(outputBuffer != null) {
384
                        if ((inputBuffer.getWidth() != outputBuffer.getWidth()) || 
385
                                        (inputBuffer.getHeight() != outputBuffer.getHeight()))
386
                                throw new MaskthresholdException("Buffer sizes not valid");
387
                }
388
                
389
                if(operationBuffer != null) {
390
                        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
391
                                if(operationBuffer.getBandCount() < inputBuffer.getBandCount())
392
                                        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.");
393
                        }
394
                }
395
        }
396
        
397
        /**
398
         * Reads a band of a buffer
399
         * @param store
400
         * @param band
401
         * @return
402
         * @throws MaskthresholdException
403
         * @throws ProcessInterruptedException
404
         */
405
        private Buffer readROBuffer(RasterDataStore store, int band) throws MaskthresholdException, ProcessInterruptedException {
406
                RasterQuery query = RasterLocator.getManager().createQuery();
407
                if(band >= 0 && band < store.getBandCount())
408
                        query.setDrawableBands(new int[]{band});
409
                else
410
                        query.setAllDrawableBands();
411
                query.setReadOnly(true);
412
                query.setAreaOfInterest();
413
                
414
                try {
415
                        return store.query(query);
416
                } catch (QueryException e) {
417
                        throw new MaskthresholdException("Error reading input raster.");
418
                }
419
        }
420
        
421
        private void write(Buffer result, Rectangle2D[] pxBbox) throws ProcessInterruptedException {
422
                if(nodata == null)
423
                        nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, result.getDataType());
424
                int colSource = (int)pxBbox[0].getX();
425
                int rowSource = (int)pxBbox[0].getY();
426
                int colOperation = colSource;
427
                int rowOperation = rowSource;
428
                if(pxBbox.length > 1) {
429
                        colOperation = (int)pxBbox[1].getX();
430
                        rowOperation = (int)pxBbox[1].getY();
431
                }
432

    
433
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
434
                opSatisfy.result = opNotSatisfy.result = result;
435
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
436
                opSatisfy.band = opNotSatisfy.band = band3;
437
                
438
                int inputInitBand = band1 < 0 ? 0 : band1;
439
                int inputEndBand = band1 < 0 ? inputBuffer.getBandCount() : band1 + 1;
440

    
441
                for (int row = 0; row < result.getHeight(); row++) {
442
                        if(pxBbox.length > 1) {
443
                                colOperation = (int)pxBbox[1].getX();
444
                                colSource = (int)pxBbox[0].getX();
445
                        }
446
                        colSource = 0;
447
                        for (int col = 0; col < result.getWidth(); col++) {
448
                                boolean compare = true;
449
                                for (int iBands = inputInitBand; iBands < inputEndBand; iBands++) {
450
                                        double op1 = getValue(inputBuffer, rowSource, colSource, iBands);
451
                                        double op2 = getValue(operationBuffer, rowOperation, colOperation, getBandToCompare(operationBuffer, iBands));
452
                                        if(!operation.compare(op1, op2)) {
453
                                                compare = false;
454
                                                break;
455
                                        }
456
                                }
457
                                if(compare) {
458
                                        opSatisfy.row = row;
459
                                        opSatisfy.col = col;
460
                                        opSatisfy.invoke();
461
                                } else {
462
                                        opNotSatisfy.row = row;
463
                                        opNotSatisfy.col = col;
464
                                        opNotSatisfy.invoke();
465
                                }
466
                                colSource ++;
467
                                colOperation++;
468
                        }
469
                        rowSource ++;
470
                        rowOperation ++;
471
                        updatePercent((int)((row * 100) / result.getHeight()), 100);
472
                }
473
        }
474

    
475
        /**
476
         * Gets the band to operate. If the buffer is null then it does not 
477
         * matter and it returns zero.
478
         * @param buf
479
         * @param inputBand
480
         * @return
481
         */
482
        private int getBandToCompare(Buffer buf, int inputBand) {
483
                if(buf == null)
484
                        return 0;
485
                if(band2 < 0)
486
                        return inputBand;
487
                else
488
                        return band2;
489
        }
490

    
491
        /**
492
         * Gets the operation value in using a double value. If there is a operation data store then
493
         * returns the value of the pixel in this position else it returns a threshold value
494
         * @param operationBuffer
495
         * @param rowOperation
496
         * @param colOperation
497
         * @return
498
         */
499
        private double getValue(Buffer buf, int rowOperation, int colOperation, int band) {
500
                if(buf == null)
501
                        return threshold;
502
                if(buf.getDataType() == Buffer.TYPE_BYTE)
503
                        return buf.getElemByte(rowOperation, colOperation, band);
504
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
505
                        return buf.getElemFloat(rowOperation, colOperation, band);
506
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
507
                        return buf.getElemDouble(rowOperation, colOperation, band);
508
                if(buf.getDataType() == Buffer.TYPE_SHORT)
509
                        return buf.getElemShort(rowOperation, colOperation, band);
510
                if(buf.getDataType() == Buffer.TYPE_INT)
511
                        return buf.getElemInt(rowOperation, colOperation, band);
512
                return 0;
513
        }
514
        
515
        public String getTitle() {
516
                return Messages.getText("maskthreshold");
517
        }
518
        
519
        abstract class AbstractOperation implements Operation {
520
                public int       row          = 0;
521
                public int       col          = 0;
522
                public Buffer    result       = null;
523
                public double    fixedValue   = 0;
524
                public Buffer    outBuffer   = null;
525
                public int       band         = 0;
526
                
527
                public void invoke() {
528
                        
529
                }
530
                public boolean compare(double a, double b) {
531
                        return false;
532
                }
533
        }
534
        
535
        class LayerOp extends AbstractOperation {
536
                public void invoke() {
537
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
538
                                if(band < 0) {
539
                                        for (int i = 0; i < result.getBandCount(); i++) {
540
                                                byte vSource = outBuffer.getElemByte(row, col, i);
541
                                                result.setElem(row, col, i, vSource);
542
                                        }
543
                                } else {
544
                                        byte vSource = outBuffer.getElemByte(row, col, band);
545
                                        result.setElem(row, col, band, vSource);
546
                                }
547
                        } else if(result.getDataType() == Buffer.TYPE_FLOAT) {
548
                                if(band < 0) {
549
                                        for (int i = 0; i < result.getBandCount(); i++) {
550
                                                float vSource = outBuffer.getElemFloat(row, col, i);
551
                                                result.setElem(row, col, i, vSource);
552
                                        }
553
                                } else {
554
                                        float vSource = outBuffer.getElemFloat(row, col, band);
555
                                        result.setElem(row, col, band, vSource);
556
                                }
557
                        } else if(result.getDataType() == Buffer.TYPE_DOUBLE) {
558
                                if(band < 0) {
559
                                        for (int i = 0; i < result.getBandCount(); i++) {
560
                                                double vSource = outBuffer.getElemDouble(row, col, i);
561
                                                result.setElem(row, col, i, vSource);
562
                                        }
563
                                } else {
564
                                        double vSource = outBuffer.getElemDouble(row, col, band);
565
                                        result.setElem(row, col, band, vSource);
566
                                }
567
                        } else if(result.getDataType() == Buffer.TYPE_SHORT) {
568
                                if(band < 0) {
569
                                        for (int i = 0; i < result.getBandCount(); i++) {
570
                                                float vSource = outBuffer.getElemShort(row, col, i);
571
                                                result.setElem(row, col, i, vSource);
572
                                        }
573
                                } else {
574
                                        float vSource = outBuffer.getElemShort(row, col, band);
575
                                        result.setElem(row, col, band, vSource);
576
                                }
577
                        } else if(result.getDataType() == Buffer.TYPE_INT) {
578
                                if(band < 0) {
579
                                        for (int i = 0; i < result.getBandCount(); i++) {
580
                                                int vSource = outBuffer.getElemInt(row, col, i);
581
                                                result.setElem(row, col, i, vSource);
582
                                        }
583
                                } else {
584
                                        int vSource = outBuffer.getElemInt(row, col, band);
585
                                        result.setElem(row, col, band, vSource);
586
                                }
587
                        }
588
                }
589
        }
590
        
591
        class TransparencyOp extends AbstractOperation {
592
                public void invoke() {
593
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
594
                                for (int i = 0; i < 3; i++) {
595
                                        byte vSource = outBuffer.getElemByte(row, col, i);
596
                                        result.setElem(row, col, i, vSource);
597
                                }
598
                                result.setElem(row, col, 4, (byte)0);
599
                        }
600
                }
601
        }
602
        
603
        class OpacityOp extends AbstractOperation {
604
                public void invoke() {
605
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
606
                                for (int i = 0; i < 3; i++) {
607
                                        byte vSource = outBuffer.getElemByte(row, col, i);
608
                                        result.setElem(row, col, i, vSource);
609
                                }
610
                                result.setElem(row, col, 4, (byte)255);
611
                        }
612
                }
613
        }
614

    
615
        class FixedValueOp extends AbstractOperation {
616
                public void invoke() {
617
                        if(result.getDataType() == Buffer.TYPE_BYTE)
618
                                result.setElem(row, col, 0, (byte)fixedValue);
619
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
620
                                result.setElem(row, col, 0, (float)fixedValue);
621
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
622
                                result.setElem(row, col, 0, fixedValue);
623
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
624
                                result.setElem(row, col, 0, (short)fixedValue);
625
                        else if(result.getDataType() == Buffer.TYPE_INT)
626
                                result.setElem(row, col, 0, (int)fixedValue);
627
                }
628
        }
629
        
630
        class NoDataOp extends AbstractOperation {
631
                public void invoke() {
632
                        if(result.getDataType() == Buffer.TYPE_BYTE)
633
                                if(band < 0) {
634
                                        for (int i = 0; i < result.getBandCount(); i++) {
635
                                                result.setElem(row, col, i, nodata.getValue().byteValue());
636
                                        }
637
                                } else {
638
                                        result.setElem(row, col, band, nodata.getValue().byteValue());
639
                                }
640
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
641
                                if(band < 0) {
642
                                        for (int i = 0; i < result.getBandCount(); i++) {
643
                                                result.setElem(row, col, i, nodata.getValue().floatValue());
644
                                        }
645
                                } else {
646
                                        result.setElem(row, col, band, nodata.getValue().floatValue());
647
                                }
648
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
649
                                if(band < 0) {
650
                                        for (int i = 0; i < result.getBandCount(); i++) {
651
                                                result.setElem(row, col, i, nodata.getValue().doubleValue());
652
                                        }
653
                                } else {
654
                                        result.setElem(row, col, band, nodata.getValue().doubleValue());
655
                                }
656
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
657
                                if(band < 0) {
658
                                        for (int i = 0; i < result.getBandCount(); i++) {
659
                                                result.setElem(row, col, i, nodata.getValue().shortValue());
660
                                        }
661
                                } else {
662
                                        result.setElem(row, col, band, nodata.getValue().shortValue());
663
                                }
664
                        else if(result.getDataType() == Buffer.TYPE_INT)
665
                                if(band < 0) {
666
                                        for (int i = 0; i < result.getBandCount(); i++) {
667
                                                result.setElem(row, col, i, nodata.getValue().intValue());
668
                                        }
669
                                } else {
670
                                        result.setElem(row, col, band, nodata.getValue().intValue());
671
                                }
672
                }
673
        }
674

    
675
        class Greater extends AbstractOperation {
676
                public boolean compare(double a, double b) {
677
                        return a > b;
678
                }
679
        }
680

    
681
        class Lower extends AbstractOperation {
682
                public boolean compare(double a, double b) {
683
                        return a < b;
684
                }
685
        }
686

    
687
        class GreaterOrEquals extends AbstractOperation {
688
                public boolean compare(double a, double b) {
689
                        return a >= b;
690
                }
691
        }
692

    
693
        class LowerOrEquals extends AbstractOperation {
694
                public boolean compare(double a, double b) {
695
                        return a <= b;
696
                }
697
        }
698
}