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

History | View | Annotate | Download (28.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
package org.gvsig.raster.tools.algorithm.maskthreshold;
23

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

    
27
import javax.swing.SwingUtilities;
28

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

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

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

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

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

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

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

    
368
                if (inputStore == null)
369
                        throw new MaskthresholdException("Layer not valid");
370
                
371
                if(operationStore != null) {
372
                        if(!inputStore.getExtent().intersects(operationStore.getExtent()))
373
                                throw new MaskthresholdException("Extents don't intersect");
374
                        if(inputStore.getCellSize() != operationStore.getCellSize())
375
                                throw new MaskthresholdException("Cell sizes are not equal");
376
                        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
377
                                if(operationStore.getBandCount() < inputStore.getBandCount())
378
                                        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.");
379
                        }
380
                }
381
        }
382
        
383
        /**
384
         * Checks input parameters for Buffers
385
         * @throws MaskthresholdException
386
         */
387
        private void checkBuffer() throws MaskthresholdException {
388
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
389
                                (outputBuffer == null || outputBuffer.getBandCount() < 3 || outputBuffer.getDataType() != Buffer.TYPE_BYTE)) {
390
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
391
                }
392

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

    
397
                if (inputBuffer == null)
398
                        throw new MaskthresholdException("Layer not valid");
399
                
400
                if(outputBuffer != null) {
401
                        if ((inputBuffer.getWidth() != outputBuffer.getWidth()) || 
402
                                        (inputBuffer.getHeight() != outputBuffer.getHeight()))
403
                                throw new MaskthresholdException("Buffer sizes not valid");
404
                }
405
                
406
                if(operationBuffer != null) {
407
                        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
408
                                if(operationBuffer.getBandCount() < inputBuffer.getBandCount())
409
                                        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.");
410
                        }
411
                }
412
        }
413
        
414
        /**
415
         * Reads a band of a buffer
416
         * @param store
417
         * @param band
418
         * @return
419
         * @throws MaskthresholdException
420
         * @throws ProcessInterruptedException
421
         */
422
        private Buffer readROBuffer(RasterDataStore store, int band) throws MaskthresholdException, ProcessInterruptedException {
423
                RasterQuery query = RasterLocator.getManager().createQuery();
424
                if(band >= 0 && band < store.getBandCount())
425
                        query.setDrawableBands(new int[]{band});
426
                else
427
                        query.setAllDrawableBands();
428
                query.setReadOnly(true);
429
                query.setAreaOfInterest();
430
                
431
                try {
432
                        return store.query(query);
433
                } catch (RasterDriverException e) {
434
                        throw new MaskthresholdException("Error reading input raster.");
435
                } catch (InvalidSetViewException e) {
436
                        throw new MaskthresholdException("Error reading input raster.");
437
                }
438
        }
439
        
440
        private void write(Buffer result, Rectangle2D[] pxBbox) {
441
                if(nodata == null)
442
                        nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, result.getDataType());
443
                int colSource = (int)pxBbox[0].getX();
444
                int rowSource = (int)pxBbox[0].getY();
445
                int colOperation = colSource;
446
                int rowOperation = rowSource;
447
                if(pxBbox.length > 1) {
448
                        colOperation = (int)pxBbox[1].getX();
449
                        rowOperation = (int)pxBbox[1].getY();
450
                }
451

    
452
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
453
                opSatisfy.result = opNotSatisfy.result = result;
454
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
455
                opSatisfy.band = opNotSatisfy.band = band3;
456
                
457
                int inputInitBand = band1 < 0 ? 0 : band1;
458
                int inputEndBand = band1 < 0 ? inputBuffer.getBandCount() : band1 + 1;
459

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

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

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

    
546
        /*
547
         * (non-Javadoc)
548
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
549
         */
550
        public int getPercent() {
551
                return percent;
552
        }
553

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

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

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

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

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

    
736
        class LowerOrEquals extends AbstractOperation {
737
                public boolean compare(double a, double b) {
738
                        return a <= b;
739
                }
740
        }
741
}