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

History | View | Annotate | Download (28.4 KB)

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

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

    
27
import javax.swing.SwingUtilities;
28

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
715
        class Greater extends AbstractOperation {
716
                public boolean compare(double a, double b) {
717
                        return a > b;
718
                }
719
        }
720

    
721
        class Lower extends AbstractOperation {
722
                public boolean compare(double a, double b) {
723
                        return a < b;
724
                }
725
        }
726

    
727
        class GreaterOrEquals extends AbstractOperation {
728
                public boolean compare(double a, double b) {
729
                        return a >= b;
730
                }
731
        }
732

    
733
        class LowerOrEquals extends AbstractOperation {
734
                public boolean compare(double a, double b) {
735
                        return a <= b;
736
                }
737
        }
738
}