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

History | View | Annotate | Download (24 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.io.File;
26
import java.util.HashMap;
27

    
28
import javax.swing.SwingUtilities;
29

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

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

    
275
                        long t2 = new java.util.Date().getTime();
276
                        milis = t2 - t1;
277
                        
278
                        SwingUtilities.invokeLater(new Runnable() {
279
                                public void run() {
280
                                        if (externalActions != null) {
281
                                                HashMap<String, Object> map = new HashMap<String, Object>();
282
                                                map.put(FILENAME, filename);
283
                                                map.put(BUFFER, resultBuffer);
284
                                                map.put(TIME, new Long(milis));
285
                                                externalActions.end(map);
286
                                        }
287
                                }
288
                        });
289
                } catch (MaskthresholdException e) {
290
                        if (incrementableTask != null)
291
                                incrementableTask.processFinalize();
292
                        messageBoxError("error_processing_maskthreshold", null, e);
293
                } finally {
294
                        if (incrementableTask != null) {
295
                                incrementableTask.processFinalize();
296
                                setProgressActive(false);
297
                        }
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
                        if(pxBbox.length > 1) {
395
                                colOperation = (int)pxBbox[1].getX();
396
                                colSource = (int)pxBbox[0].getX();
397
                        }
398
                        colSource = 0;
399
                        for (int col = 0; col < result.getWidth(); col++) {
400
                                double op1 = getValue(inputBuffer, rowSource, colSource);
401
                                double op2 = getValue(operationBuffer, rowOperation, colOperation);
402
                                if(operation.compare(op1, op2)) {
403
                                        opSatisfy.row = row;
404
                                        opSatisfy.col = col;
405
                                        opSatisfy.invoke();
406
                                } else {
407
                                        opNotSatisfy.row = row;
408
                                        opNotSatisfy.col = col;
409
                                        opNotSatisfy.invoke();
410
                                }
411
                                colSource ++;
412
                                colOperation++;
413
                        }
414
                        rowSource ++;
415
                        rowOperation ++;
416
                        percent = (int)((row * 100) / result.getHeight());
417
                }
418
        }
419

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

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

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

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

    
628
        class Greater extends AbstractOperation {
629
                public boolean compare(double a, double b) {
630
                        return a > b;
631
                }
632
        }
633

    
634
        class Lower extends AbstractOperation {
635
                public boolean compare(double a, double b) {
636
                        return a < b;
637
                }
638
        }
639

    
640
        class GreaterOrEquals extends AbstractOperation {
641
                public boolean compare(double a, double b) {
642
                        return a >= b;
643
                }
644
        }
645

    
646
        class LowerOrEquals extends AbstractOperation {
647
                public boolean compare(double a, double b) {
648
                        return a <= b;
649
                }
650
        }
651
}