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

History | View | Annotate | Download (23.9 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>Fixed-oplayer:  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>Fixed-threshold:  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>Replicate-oplayer:  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>Replicate-threshold:  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>Transparent-oplayer: 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>Transparent-threshold: 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>Opacity-oplayer: 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>Opacity-threshold: 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
 *
77
 * 10/12/2007
78
 * @author Nacho Brodin nachobrodin@gmail.com
79
 */
80
public class MaskthresholdProcess extends RasterProcess {
81
        //Possible input parameters
82
        public static String      RASTER_STORE1    = "RasterStore1";
83
        public static String      RASTER_STORE2    = "RasterStore2";
84
        public static String      RASTER_STORE3    = "RasterStore3";
85
        public static String      RASTER_BUFFER1   = "Buffer1";
86
        public static String      RASTER_BUFFER2   = "Buffer2";
87
        public static String      RASTER_BUFFER3   = "Buffer3";
88
        public static String      BAND1            = "Band1";
89
        public static String      BAND2            = "Band2";
90
        public static String      BAND3            = "Band3";
91
        public static String      THRESHOLD        = "Threshold";
92
        public static String      FIXED_VALUE      = "FixedValue";
93
        public static String      OPERATION        = "Operation";
94
        public static String      SATISFY_METHOD   = "Satisfy_Method";
95
        public static String      PATH             = "Path";
96
        
97
        //Possible output parameters
98
        public static String      BUFFER           = "Buffer";
99
        public static String      FILENAME         = "FileName";
100
        public static String      TIME             = "Time";
101
        
102
        public static String[]    MASK_OPERATIONS  = new String[]{"Greater", "Lower", 
103
                                                                      "GreaterOrEquals", "LoweOrEquals"};
104
        public static String[]    OUTPUT_METHODS   = new String[]{"NoData", "FixedValue", 
105
                                                                      "Transparency", "Opacity", 
106
                                                                      "LayerAndBandsSelected", "LayerAndBandsSelectedInverse"};
107
        
108
        private RasterDataStore   inputStore       = null;
109
        private RasterDataStore   operationStore   = null;
110
        private RasterDataStore   outputStore      = null;
111
        private Buffer            inputBuffer      = null;
112
        private Buffer            operationBuffer  = null;
113
        private Buffer            outputBuffer     = null;
114
        private int               band1            = 0;
115
        private int               band2            = 0;
116
        private int               band3            = 0; //-1 All
117
        private int               resultNumBands   = 0;
118
        
119
        private String            filename         = null; //If is null only returns a buffer
120
        private double            threshold        = 0;
121
        private double            fixedValue       = 0;
122
        private NoData            nodata           = null;
123
        private AbstractOperation operation        = null;
124
        private AbstractOperation opSatisfy        = null;
125
        private AbstractOperation opNotSatisfy     = null;
126
        private long              milis            = 0;
127
        private int               percent          = 0;
128
        private Buffer            resultBuffer     = null;
129
        
130
        public static void registerParameters() {
131
                RASTER_STORE1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE1, RasterDataStore.class);
132
                RASTER_STORE2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE2, RasterDataStore.class);
133
                RASTER_STORE3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE3, RasterDataStore.class);
134
                
135
                RASTER_BUFFER1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER1, Buffer.class);
136
                RASTER_BUFFER2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER2, Buffer.class);
137
                RASTER_BUFFER3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER3, Buffer.class);
138
                
139
                BAND1 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND1, Integer.class);
140
                BAND2 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND2, Integer.class);
141
                BAND3 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND3, Integer.class);
142
                
143
                SATISFY_METHOD = RasterBaseAlgorithmLibrary.registerInputParameter(SATISFY_METHOD, Integer.class);
144
                
145
                THRESHOLD = RasterBaseAlgorithmLibrary.registerInputParameter(THRESHOLD, Double.class);
146
                FIXED_VALUE = RasterBaseAlgorithmLibrary.registerInputParameter(FIXED_VALUE, Double.class);
147
                OPERATION = RasterBaseAlgorithmLibrary.registerInputParameter(OPERATION, Integer.class);
148
                
149
                PATH = RasterBaseAlgorithmLibrary.registerInputParameter(PATH, String.class);
150
                FILENAME = RasterBaseAlgorithmLibrary.registerOutputParameter(FILENAME, String.class);
151
                BUFFER = RasterBaseAlgorithmLibrary.registerOutputParameter(BUFFER, Buffer.class);
152
        }
153
        
154
        /*
155
         * (non-Javadoc)
156
         * @see org.gvsig.rastertools.RasterProcess#init()
157
         */
158
        public void init() {
159
                inputStore = getParam(RASTER_STORE1) != null ? (RasterDataStore)getParam(RASTER_STORE1) : null; //M
160
                operationStore = getParam(RASTER_STORE2) != null ? (RasterDataStore)getParam(RASTER_STORE2) : null; //Default Null
161
                outputStore = getParam(RASTER_STORE3) != null ? (RasterDataStore)getParam(RASTER_STORE3) : null; //Default Null
162
                
163
                inputBuffer = getParam(RASTER_BUFFER1) != null ? (Buffer)getParam(RASTER_BUFFER1) : null;
164
                operationBuffer = getParam(RASTER_BUFFER2) != null ? (Buffer)getParam(RASTER_BUFFER2) : null;
165
                outputBuffer = getParam(RASTER_BUFFER3) != null ? (Buffer)getParam(RASTER_BUFFER3) : null;
166
                
167
                band1 = (Integer)getIntParam(BAND1); //Default 0
168
                band2 = (Integer)getIntParam(BAND2); //Default 0
169
                band3 = (Integer)getIntParam(BAND3); //Default 0
170
                
171
                int satisfy = (Integer)getIntParam(SATISFY_METHOD); //Default 0
172
                
173
                if(satisfy == 0) {
174
                        opSatisfy = new NoDataOp();
175
                        opNotSatisfy = new FixedValueOp();
176
                        resultNumBands = 1;
177
                }
178
                if(satisfy == 1) {
179
                        opSatisfy = new FixedValueOp();
180
                        opNotSatisfy = new NoDataOp();
181
                        resultNumBands = 1;
182
                }
183
                if(satisfy == 2) {
184
                        opSatisfy = new TransparencyOp();
185
                        opNotSatisfy = new OpacityOp();
186
                        resultNumBands = 4;
187
                }
188
                if(satisfy == 3) {
189
                        opSatisfy = new OpacityOp();
190
                        opNotSatisfy = new TransparencyOp();
191
                        resultNumBands = 4;
192
                }
193
                if(satisfy == 4) {
194
                        opSatisfy = new LayerOp();
195
                        opNotSatisfy = new NoDataOp();
196
                }
197
                if(satisfy == 5) {
198
                        opSatisfy = new NoDataOp();
199
                        opNotSatisfy = new LayerOp();
200
                }
201
                if(satisfy == 4 || satisfy == 5) {
202
                        if(outputStore != null)
203
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputStore.getBandCount();
204
                        if(outputBuffer != null)
205
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputBuffer.getBandCount();
206
                }
207
                
208
                int op = (Integer)getIntParam(OPERATION); //Default 0
209
                if(op == 0)
210
                        operation = new Greater();
211
                if(op == 1)
212
                        operation = new Lower();
213
                if(op == 2)
214
                        operation = new GreaterOrEquals();
215
                if(op == 3)
216
                        operation = new LowerOrEquals();
217
                threshold = (Double)getDoubleParam(THRESHOLD); //Default 0
218
                fixedValue = (Double)getDoubleParam(FIXED_VALUE); //Default 0
219
                
220
                filename = getStringParam(PATH);
221
        }
222
        
223
        /**
224
         * M?todo donde se ejecutar? el Thread, aqu? se reproyecta el raster.
225
         */
226
        public void process() throws ProcessInterruptedException, ProcessException {
227
                long t1 = new java.util.Date().getTime();
228
                insertLineLog(Messages.getText("maskthreshold"));
229
                int result = 1;
230
                
231
                try {
232
                        if(inputStore != null)
233
                                checkStore();
234
                        else
235
                                checkBuffer();
236
                        
237
                        Rectangle2D[] pxBBox = null;
238
                        
239
                        if(inputStore != null) {
240
                                inputBuffer = readROBuffer(inputStore, band1);
241
                                RasterDataStore[] storeList = new RasterDataStore[]{inputStore, operationStore, outputStore};
242
                                pxBBox = getIntersectionInPxCoords(storeList);
243
                        } else {
244
                                pxBBox = new Rectangle2D[]{
245
                                        new Rectangle2D.Double(0, 0, inputBuffer.getWidth(), inputBuffer.getHeight())
246
                                        };
247
                        }
248
                        
249
                        if(operationStore != null) 
250
                                operationBuffer = readROBuffer(operationStore, band2);
251
                        
252
                        int dataType = Buffer.TYPE_DOUBLE;
253
                        
254
                        if(outputStore != null) { 
255
                                outputBuffer = readROBuffer(outputStore, band3);
256
                                dataType = outputBuffer.getDataType();
257
                        }
258
                        
259
                        resultBuffer = RasterLocator.getManager().createBuffer(
260
                                        dataType, 
261
                                        (int)pxBBox[0].getWidth(), 
262
                                        (int)pxBBox[0].getHeight(), 
263
                                        resultNumBands, true);
264
                        
265
                        write(resultBuffer, pxBBox);
266
                        
267
                        if(filename != null)
268
                                exportRaster(filename, resultBuffer, inputStore.getCellSize(), 
269
                                                inputStore.getExtent().getULX(), inputStore.getExtent().getULY());
270

    
271
                        if(result != 0) {
272
                                if (incrementableTask != null) {
273
                                        incrementableTask.processFinalize();
274
                                        setProgressActive(false);
275
                                }
276
                                messageBoxError("transformation_not_possible", null);
277
                                return;
278
                        }
279

    
280
                        long t2 = new java.util.Date().getTime();
281
                        milis = t2 - t1;
282
                        
283
                        SwingUtilities.invokeLater(new Runnable() {
284
                                public void run() {
285
                                        if (externalActions != null) {
286
                                                HashMap<String, Object> map = new HashMap<String, Object>();
287
                                                map.put(FILENAME, filename);
288
                                                map.put(BUFFER, resultBuffer);
289
                                                map.put(TIME, new Long(milis));
290
                                                externalActions.end(map);
291
                                        }
292
                                }
293
                        });
294
                } catch (MaskthresholdException e) {
295
                        if (incrementableTask != null)
296
                                incrementableTask.processFinalize();
297
                        messageBoxError("error_reprojecting", this, e);
298
                }
299
        }
300
        
301
        /**
302
         * Checks input parameters for DataStores
303
         * @throws MaskthresholdException
304
         */
305
        private void checkStore() throws MaskthresholdException {
306
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
307
                                (outputStore == null || outputStore.getBandCount() < 3 || outputStore.getDataType()[0] != Buffer.TYPE_BYTE)) {
308
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
309
                }
310

    
311
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
312
                                outputStore == null)
313
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
314

    
315
                if (inputStore == null)
316
                        throw new MaskthresholdException("Layer not valid");
317
                
318
                if(operationStore != null) {
319
                        if(!inputStore.getExtent().intersects(operationStore.getExtent()))
320
                                throw new MaskthresholdException("Extents don't intersect");
321
                        if(inputStore.getCellSize() != operationStore.getCellSize())
322
                                throw new MaskthresholdException("Cell sizes are not equal");
323
                }
324
        }
325
        
326
        /**
327
         * Checks input parameters for Buffers
328
         * @throws MaskthresholdException
329
         */
330
        private void checkBuffer() throws MaskthresholdException {
331
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
332
                                (outputBuffer == null || outputBuffer.getBandCount() < 3 || outputBuffer.getDataType() != Buffer.TYPE_BYTE)) {
333
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
334
                }
335

    
336
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
337
                                outputBuffer == null)
338
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
339

    
340
                if (inputBuffer == null)
341
                        throw new MaskthresholdException("Layer not valid");
342
                
343
                if(outputBuffer != null && 
344
                  ((inputBuffer.getWidth() != outputBuffer.getWidth()) || 
345
                   (inputBuffer.getHeight() != outputBuffer.getHeight()) ||
346
                   (inputStore.getCellSize() != outputStore.getCellSize())) )
347
                        throw new MaskthresholdException("Buffer sizes not valid");
348
        }
349
        
350
        /**
351
         * Reads a band of a buffer
352
         * @param store
353
         * @param band
354
         * @return
355
         * @throws MaskthresholdException
356
         * @throws ProcessInterruptedException
357
         */
358
        private Buffer readROBuffer(RasterDataStore store, int band) throws MaskthresholdException, ProcessInterruptedException {
359
                RasterQuery query = RasterLocator.getManager().createQuery();
360
                if(band >= 0 && band < store.getBandCount())
361
                        query.setDrawableBands(new int[]{band});
362
                else
363
                        query.setAllDrawableBands();
364
                query.setReadOnly(true);
365
                query.setAreaOfInterest();
366
                
367
                try {
368
                        return store.query(query);
369
                } catch (RasterDriverException e) {
370
                        throw new MaskthresholdException("Error reading input raster.");
371
                } catch (InvalidSetViewException e) {
372
                        throw new MaskthresholdException("Error reading input raster.");
373
                }
374
        }
375
        
376
        private void write(Buffer result, Rectangle2D[] pxBbox) {
377
                if(nodata == null)
378
                        nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, result.getDataType());
379
                int colSource = (int)pxBbox[0].getX();
380
                int rowSource = (int)pxBbox[0].getY();
381
                int colOperation = colSource;
382
                int rowOperation = rowSource;
383
                if(pxBbox.length > 1) {
384
                        colOperation = (int)pxBbox[1].getX();
385
                        rowOperation = (int)pxBbox[1].getY();
386
                }
387

    
388
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
389
                opSatisfy.result = opNotSatisfy.result = result;
390
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
391
                opSatisfy.band = opNotSatisfy.band = band3;
392

    
393
                for (int row = 0; row < result.getHeight(); row++) {
394
                        colOperation = (int)pxBbox[1].getX();
395
                        colSource = (int)pxBbox[0].getX();
396
                        for (int col = 0; col < result.getWidth(); col++) {
397
                                double op1 = getValue(inputBuffer, rowSource, colSource);
398
                                double op2 = getValue(operationBuffer, rowOperation, colOperation);
399
                                if(operation.compare(op1, op2)) {
400
                                        opSatisfy.row = row;
401
                                        opSatisfy.col = col;
402
                                        opSatisfy.invoke();
403
                                } else {
404
                                        opNotSatisfy.row = row;
405
                                        opNotSatisfy.col = col;
406
                                        opNotSatisfy.invoke();
407
                                }
408
                                colSource ++;
409
                                colOperation++;
410
                        }
411
                        rowSource ++;
412
                        rowOperation ++;
413
                        percent = (int)((row * 100) / result.getHeight());
414
                }
415
        }
416

    
417
        /**
418
         * Gets the operation value in using a double value. If there is a operation data store then
419
         * returns the value of the pixel in this position else it returns a threshold value
420
         * @param operationBuffer
421
         * @param rowOperation
422
         * @param colOperation
423
         * @return
424
         */
425
        private double getValue(Buffer buf, int rowOperation, int colOperation) {
426
                if(buf == null)
427
                        return threshold;
428
                if(buf.getDataType() == Buffer.TYPE_BYTE)
429
                        return buf.getElemByte(rowOperation, colOperation, 0);
430
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
431
                        return buf.getElemFloat(rowOperation, colOperation, 0);
432
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
433
                        return buf.getElemDouble(rowOperation, colOperation, 0);
434
                if(buf.getDataType() == Buffer.TYPE_SHORT)
435
                        return buf.getElemShort(rowOperation, colOperation, 0);
436
                if(buf.getDataType() == Buffer.TYPE_INT)
437
                        return buf.getElemInt(rowOperation, colOperation, 0);
438
                return 0;
439
        }
440
        
441
        /*
442
         * (non-Javadoc)
443
         * @see org.gvsig.raster.tools.app.basic.raster.process.RasterProcess#getResult()
444
         */
445
        public Object getResult() {
446
                HashMap<String, Object> map = new HashMap<String, Object>();
447
                map.put(FILENAME, filename);
448
                map.put(BUFFER, resultBuffer);
449
                map.put(TIME, new Long(milis));
450
                return map;
451
        }
452

    
453
        /*
454
         * (non-Javadoc)
455
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
456
         */
457
        public int getPercent() {
458
                return percent;
459
        }
460

    
461
        /*
462
         * (non-Javadoc)
463
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
464
         */
465
        public String getTitle() {
466
                return Messages.getText("maskthreshold");
467
        }
468
        
469
        abstract class AbstractOperation implements Operation {
470
                public int       row          = 0;
471
                public int       col          = 0;
472
                public Buffer    result       = null;
473
                public double    fixedValue   = 0;
474
                public Buffer    outBuffer   = null;
475
                public int       band         = 0;
476
                
477
                public void invoke() {
478
                        
479
                }
480
                public boolean compare(double a, double b) {
481
                        return false;
482
                }
483
        }
484
        
485
        class LayerOp extends AbstractOperation {
486
                public void invoke() {
487
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
488
                                if(band < 0) {
489
                                        for (int i = 0; i < result.getBandCount(); i++) {
490
                                                byte vSource = outBuffer.getElemByte(row, col, i);
491
                                                result.setElem(row, col, i, vSource);
492
                                        }
493
                                } else {
494
                                        byte vSource = outBuffer.getElemByte(row, col, band);
495
                                        result.setElem(row, col, band, vSource);
496
                                }
497
                        } else if(result.getDataType() == Buffer.TYPE_FLOAT) {
498
                                if(band < 0) {
499
                                        for (int i = 0; i < result.getBandCount(); i++) {
500
                                                float vSource = outBuffer.getElemFloat(row, col, i);
501
                                                result.setElem(row, col, i, vSource);
502
                                        }
503
                                } else {
504
                                        float vSource = outBuffer.getElemFloat(row, col, band);
505
                                        result.setElem(row, col, band, vSource);
506
                                }
507
                        } else if(result.getDataType() == Buffer.TYPE_DOUBLE) {
508
                                if(band < 0) {
509
                                        for (int i = 0; i < result.getBandCount(); i++) {
510
                                                double vSource = outBuffer.getElemDouble(row, col, i);
511
                                                result.setElem(row, col, i, vSource);
512
                                        }
513
                                } else {
514
                                        double vSource = outBuffer.getElemDouble(row, col, band);
515
                                        result.setElem(row, col, band, vSource);
516
                                }
517
                        } else if(result.getDataType() == Buffer.TYPE_SHORT) {
518
                                if(band < 0) {
519
                                        for (int i = 0; i < result.getBandCount(); i++) {
520
                                                float vSource = outBuffer.getElemShort(row, col, i);
521
                                                result.setElem(row, col, i, vSource);
522
                                        }
523
                                } else {
524
                                        float vSource = outBuffer.getElemShort(row, col, band);
525
                                        result.setElem(row, col, band, vSource);
526
                                }
527
                        } else if(result.getDataType() == Buffer.TYPE_INT) {
528
                                if(band < 0) {
529
                                        for (int i = 0; i < result.getBandCount(); i++) {
530
                                                int vSource = outBuffer.getElemInt(row, col, i);
531
                                                result.setElem(row, col, i, vSource);
532
                                        }
533
                                } else {
534
                                        int vSource = outBuffer.getElemInt(row, col, band);
535
                                        result.setElem(row, col, band, vSource);
536
                                }
537
                        }
538
                }
539
        }
540
        
541
        class TransparencyOp extends AbstractOperation {
542
                public void invoke() {
543
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
544
                                for (int i = 0; i < 3; i++) {
545
                                        byte vSource = outBuffer.getElemByte(row, col, i);
546
                                        result.setElem(row, col, i, vSource);
547
                                }
548
                                result.setElem(row, col, 4, (byte)0);
549
                        }
550
                }
551
        }
552
        
553
        class OpacityOp extends AbstractOperation {
554
                public void invoke() {
555
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
556
                                for (int i = 0; i < 3; i++) {
557
                                        byte vSource = outBuffer.getElemByte(row, col, i);
558
                                        result.setElem(row, col, i, vSource);
559
                                }
560
                                result.setElem(row, col, 4, (byte)255);
561
                        }
562
                }
563
        }
564

    
565
        class FixedValueOp extends AbstractOperation {
566
                public void invoke() {
567
                        if(result.getDataType() == Buffer.TYPE_BYTE)
568
                                result.setElem(row, col, 0, (byte)fixedValue);
569
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
570
                                result.setElem(row, col, 0, (float)fixedValue);
571
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
572
                                result.setElem(row, col, 0, fixedValue);
573
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
574
                                result.setElem(row, col, 0, (short)fixedValue);
575
                        else if(result.getDataType() == Buffer.TYPE_INT)
576
                                result.setElem(row, col, 0, (int)fixedValue);
577
                }
578
        }
579
        
580
        class NoDataOp extends AbstractOperation {
581
                public void invoke() {
582
                        if(result.getDataType() == Buffer.TYPE_BYTE)
583
                                if(band < 0) {
584
                                        for (int i = 0; i < result.getBandCount(); i++) {
585
                                                result.setElem(row, col, i, nodata.getValue().byteValue());
586
                                        }
587
                                } else {
588
                                        result.setElem(row, col, band, nodata.getValue().byteValue());
589
                                }
590
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
591
                                if(band < 0) {
592
                                        for (int i = 0; i < result.getBandCount(); i++) {
593
                                                result.setElem(row, col, i, nodata.getValue().floatValue());
594
                                        }
595
                                } else {
596
                                        result.setElem(row, col, band, nodata.getValue().floatValue());
597
                                }
598
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
599
                                if(band < 0) {
600
                                        for (int i = 0; i < result.getBandCount(); i++) {
601
                                                result.setElem(row, col, i, nodata.getValue().doubleValue());
602
                                        }
603
                                } else {
604
                                        result.setElem(row, col, band, nodata.getValue().doubleValue());
605
                                }
606
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
607
                                if(band < 0) {
608
                                        for (int i = 0; i < result.getBandCount(); i++) {
609
                                                result.setElem(row, col, i, nodata.getValue().shortValue());
610
                                        }
611
                                } else {
612
                                        result.setElem(row, col, band, nodata.getValue().shortValue());
613
                                }
614
                        else if(result.getDataType() == Buffer.TYPE_INT)
615
                                if(band < 0) {
616
                                        for (int i = 0; i < result.getBandCount(); i++) {
617
                                                result.setElem(row, col, i, nodata.getValue().intValue());
618
                                        }
619
                                } else {
620
                                        result.setElem(row, col, band, nodata.getValue().intValue());
621
                                }
622
                }
623
        }
624

    
625
        class Greater extends AbstractOperation {
626
                public boolean compare(double a, double b) {
627
                        return a > b;
628
                }
629
        }
630

    
631
        class Lower extends AbstractOperation {
632
                public boolean compare(double a, double b) {
633
                        return a < b;
634
                }
635
        }
636

    
637
        class GreaterOrEquals extends AbstractOperation {
638
                public boolean compare(double a, double b) {
639
                        return a >= b;
640
                }
641
        }
642

    
643
        class LowerOrEquals extends AbstractOperation {
644
                public boolean compare(double a, double b) {
645
                        return a <= b;
646
                }
647
        }
648
}