Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / datastruct / TransparencyRangeImpl.java @ 2623

History | View | Annotate | Download (13.1 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.impl.datastruct;
23

    
24
import java.io.IOException;
25
import java.util.Arrays;
26

    
27
import org.gvsig.fmap.dal.coverage.datastruct.TransparencyRange;
28
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
29
import org.gvsig.tools.ToolsLocator;
30
import org.gvsig.tools.dynobject.DynStruct;
31
import org.gvsig.tools.persistence.PersistenceManager;
32
import org.gvsig.tools.persistence.PersistentState;
33
import org.gvsig.tools.persistence.exception.PersistenceException;
34
/**
35
 * Clase que representa a un conjunto de pixeles con transparencia. Incluye los
36
 * rangos de transparencia para cada banda, la cadena que va en la lista y la
37
 * operaci?n que se realiza entre ellos. Un And significa que ser?n
38
 * transparentes todos los pixeles que cumplan con R con G y con B. Un Or
39
 * significar? que tendr?n transparencia todos los pixeles que cumplan con R con
40
 * G o con B.
41
 *
42
 * @author Nacho Brodin (nachobrodin@gmail.com)
43
 */
44
public class TransparencyRangeImpl implements TransparencyRange, Cloneable {
45
        private String  strEntry = null;
46
        private int[]   red      = null;
47
        private int[]   green    = null;
48
        private int[]   blue     = null;
49
        private boolean and      = true;
50
        private int     alpha    = 0;
51

    
52
        /**
53
         * Constructor
54
         */
55
        public TransparencyRangeImpl() {
56
        }
57

    
58
        /**
59
         * Crea un objeto TransparencyRange a partir de una cadena bien formada
60
         * @param value cadena bien formada que representa un intervalo
61
         */
62
        public TransparencyRangeImpl(String value) {
63
                try {
64
                        red = new int[2];
65
                        green = new int[2];
66
                        blue = new int[2];
67
                        and = stringToInterval(value, red, green, blue);
68
                        strEntry = value;
69
                } catch (IOException e) {
70
                        // Cadena mal formada
71
                }
72
        }
73

    
74
        
75
        /**
76
         * Obtiene la operaci?n  utilizada
77
         * @param and Si es true significa que se usa un AND y false implica
78
         * que se usa un OR
79
         */
80
        public boolean isAnd() {
81
                return and;
82
        }
83

    
84
        /**
85
         * Asigna la operaci?n AND como la utilizada
86
         * @param and booleano que si est? a true significa que el la operaci?n
87
         * AND es la utilizada como operaci?n.
88
         */
89
        public void setAnd(boolean and) {
90
                this.and = and;
91
        }
92

    
93
        /**
94
         * Obtiene el intervalo de valores correspondiente a la banda del azul
95
         * @return Array bidimensional de enteros correspondiente a la banda del azul
96
         */
97
        public int[] getBlue() {
98
                return blue;
99
        }
100

    
101
        /**
102
         * Asigna los intervalos de valores correspondientes a las bandas del
103
         * rojo, azul y verde
104
         * @param red Array bidimensional de enteros correspondiente a la banda del rojo
105
         * @param green Array bidimensional de enteros correspondiente a la banda del verde
106
         * @param blue Array bidimensional de enteros correspondiente a la banda del azul
107
         */
108
        public void setRGB(int[] red, int[] green, int[] blue) {
109
                this.red = red;
110
                this.green = green;
111
                this.blue = blue;
112
        }
113

    
114
        /**
115
         * Asigna el intervalo de valores correspondiente a la banda del azul
116
         * @param blue Array bidimensional de enteros correspondiente a la banda del azul
117
         */
118
        public void setBlue(int[] blue) {
119
                this.blue = blue;
120
        }
121

    
122
        /**
123
         * Obtiene el intervalo de valores correspondiente a la banda del verde
124
         * @return Array bidimensional de enteros correspondiente a la banda del verde
125
         */
126
        public int[] getGreen() {
127
                return green;
128
        }
129

    
130
        /**
131
         * Asigna el intervalo de valores correspondiente a la banda del verde
132
         * @param green Array bidimensional de enteros correspondiente a la banda del verde
133
         */
134
        public void setGreen(int[] green) {
135
                this.green = green;
136
        }
137

    
138
        /**
139
         * Obtiene el intervalo de valores correspondiente a la banda del rojo
140
         * @return Array bidimensional de enteros correspondiente a la banda del rojo
141
         */
142
        public int[] getRed() {
143
                return red;
144
        }
145

    
146
        /**
147
         * Asigna el intervalo de valores correspondiente a la banda del rojo
148
         * @param red Array bidimensional de enteros correspondiente a la banda del rojo
149
         */
150
        public void setRed(int[] red) {
151
                this.red = red;
152
        }
153

    
154
        /**
155
         * Obtiene la cadena que representa una entrada en la tabla.
156
         * @return Cadena que representa una entrada en la tabla
157
         */
158
        public String getStrEntry() {
159
                return strEntry;
160
        }
161

    
162
        /**
163
         * Asigna la cadena que representa una entrada en la tabla.
164
         * @param strEntry Cadena que representa una entrada en la tabla.
165
         */
166
        public void setStrEntry(String strEntry) {
167
                this.strEntry = strEntry;
168
        }
169

    
170
        /**
171
         * Esta funci?n valida la cadena de entrada por medio de una m?quina de estados. Valida las
172
         * siguientes posibilidades en la cadena de entrada:
173
         * <LI>
174
         * <UL>(valor_rojo) & (Valor_verde) & (Valor_azul)</UL>
175
         * <UL>(valor_rojo) | (Valor_verde) | (Valor_azul)</UL>
176
         * </LI>
177
         * Despues de la validaci?n parsea el contenido y carga los par?metros r,g,b con los
178
         * intervalos de valores. Estos par?metros deben ser pasados como arrays de enteros de
179
         * dos elementos.
180
         * @param values
181
         * @param r        Intervalo de rojo
182
         * @param g Intervalo de verde
183
         * @param b Intervalo de azul
184
         * @return Devuelve true si la operaci?n usada en los intervalos es un AND y false si es un OR
185
         */
186
        public boolean stringToInterval(String values, int[] r, int[] g, int[] b) throws IOException {
187
                int status = 0;
188
                int countAnd = 0, countOr = 0;
189
                boolean and = true;
190
                for (int i = 0; i < values.length(); i++) {
191
                        char c = values.charAt(i);
192
                        switch (status) {
193
                                case 0:
194
                                        if (c == ' ')
195
                                                status = 0;
196
                                        else if ((c >= 48 && c <= 57) || c == '*')
197
                                                status = 1;
198
                                        else
199
                                                status = 4;
200
                                        break;
201
                                case 1:
202
                                        if ((c >= 48 && c <= 57) || (c == ' '))
203
                                                status = 1;
204
                                        else if (c == ':')
205
                                                status = 2;
206
                                        else if (c == '&') {
207
                                                status = 0;
208
                                                countAnd++;
209
                                        } else if (c == '|') {
210
                                                status = 0;
211
                                                countOr++;
212
                                        } else
213
                                                status = 4;
214
                                        break;
215
                                case 2:
216
                                        if (c >= 48 && c <= 57)
217
                                                status = 3;
218
                                        else
219
                                                status = 4;
220
                                        break;
221
                                case 3:
222
                                        if ((c >= 48 && c <= 57) || (c == ' '))
223
                                                status = 3;
224
                                        else if (c == '&') {
225
                                                status = 0;
226
                                                countAnd++;
227
                                        } else if (c == '|') {
228
                                                status = 0;
229
                                                countOr++;
230
                                        } else
231
                                                status = 4;
232
                                        break;
233
                                case 4:
234
                                        throw new IOException("Error en la cadena de entrada " + status);
235
                        }
236
                }
237

    
238
                // Si el analisis es correcto parseamos
239
                if ((status == 1 || status == 3) && ((countAnd == 2 && countOr == 0) || (countAnd == 0 && countOr == 2))) {
240
                        String[] s = values.split(" & ");
241
                        if (s.length < 3) {
242
                                s = values.split(" \\| ");
243
                                and = false;
244
                        }
245
                        ;
246
                        String[] val = s[0].split(":");
247
                        try {
248
                                r[0] = Integer.parseInt(val[0]);
249
                                if (val.length == 2)
250
                                        r[1] = Integer.parseInt(val[1]);
251
                                else
252
                                        r[1] = Integer.parseInt(val[0]);
253
                        } catch (NumberFormatException e) {
254
                                r[0] = -1;
255
                                r[1] = -1;
256
                        }
257

    
258
                        val = s[1].split(":");
259
                        try {
260
                                g[0] = Integer.parseInt(val[0]);
261
                                if (val.length == 2)
262
                                        g[1] = Integer.parseInt(val[1]);
263
                                else
264
                                        g[1] = Integer.parseInt(val[0]);
265
                        } catch (NumberFormatException e) {
266
                                g[0] = -1;
267
                                g[1] = -1;
268
                        }
269

    
270
                        val = s[2].split(":");
271
                        try {
272
                                b[0] = Integer.parseInt(val[0]);
273
                                if (val.length == 2)
274
                                        b[1] = Integer.parseInt(val[1]);
275
                                else
276
                                        b[1] = Integer.parseInt(val[0]);
277
                        } catch (NumberFormatException e) {
278
                                b[0] = -1;
279
                                b[1] = -1;
280
                        }
281
                } else
282
                        throw new IOException("Error en la cadena de entrada ");
283

    
284
                return and;
285
        }
286

    
287
        /**
288
         * Carga la cadena StrEntry leyendo los valores en los vectores que representa los intervalos.
289
         */
290
        public void loadStrEntryFromValues(){
291
                String separator = " | ";
292
                if (and)
293
                        separator = " & ";
294
                strEntry = String.valueOf(red[0] + separator+ green[0] + separator + blue[0]);
295
        }
296

    
297
        /**
298
         * Obtiene el alpha asociado al rango. Por defecto es de 0, es decir
299
         * totalmente transparente pero puede asociarsele un valor distinto
300
         * @return Alpha asociado
301
         */
302
        public int getAlpha() {
303
                return alpha;
304
        }
305

    
306
        /**
307
         * Asigna el alpha asociado al rango. Por defecto es de 0, es decir
308
         * totalmente transparente pero puede asociarsele un valor distinto
309
         * @param alpha asociado
310
         */
311
        public void setAlpha(int alpha) {
312
                this.alpha = alpha;
313
        }
314

    
315
        /**
316
         * Realiza la uni?n entre el intervalo actual y el pasado por par?metro
317
         * @param interval intervalo pasado
318
         * @param rgb
319
         * @return union de intervalos
320
         */
321
        public int[] union(int[] interval, int rgb) {
322
                switch (rgb) {
323
                        case AbstractRasterProvider.RED_BAND:
324
                                if ((red[1] >= interval[0] && red[0] <= interval[0]) || (red[0] <= interval[1] && red[0] >= interval[0]))
325
                                        return new int[] { Math.min(red[0], interval[0]), Math.max(red[1], interval[1]) };
326
                        case AbstractRasterProvider.GREEN_BAND:
327
                                if ((green[1] >= interval[0] && green[0] <= interval[0]) || (green[0] <= interval[1] && green[0] >= interval[0]))
328
                                        return new int[] { Math.min(green[0], interval[0]), Math.max(green[1], interval[1]) };
329
                        case AbstractRasterProvider.BLUE_BAND:
330
                                if ((blue[1] >= interval[0] && blue[0] <= interval[0]) || (blue[0] <= interval[1] && blue[0] >= interval[0]))
331
                                        return new int[] { Math.min(blue[0], interval[0]), Math.max(blue[1], interval[1]) };
332
                }
333
                return null;
334
        }
335

    
336
        /**
337
         * Muestra los datos del objeto para depuraci?n.
338
         */
339
        public void show(){
340
                if (getRed() != null)
341
                        System.out.println(getRed()[0] + " " + getRed()[1]);
342
                if (getGreen() != null)
343
                        System.out.println(getGreen()[0] + " " + getGreen()[1]);
344
                if (getBlue() != null)
345
                        System.out.println(getBlue()[0] + " " + getBlue()[1]);
346
                System.out.println(isAnd());
347
                System.out.println(getStrEntry());
348
                System.out.println("--------------------");
349
        }
350

    
351
        public Object clone() {
352
                TransparencyRangeImpl clone = null;
353
                try {
354
                        clone = (TransparencyRangeImpl) super.clone();
355
                } catch (CloneNotSupportedException e) {
356
                }
357

    
358
                if (strEntry != null)
359
                        clone.strEntry = new String(strEntry);
360

    
361
                if (red != null)
362
                        clone.red = (int[]) red.clone();
363

    
364
                if (green != null)
365
                        clone.green = (int[]) green.clone();
366

    
367
                if (blue != null)
368
                        clone.blue = (int[]) blue.clone();
369

    
370
                return clone;
371
        }
372

    
373
        public int hashCode() {
374
                final int PRIME = 31;
375
                int result = 1;
376
                result = PRIME * result + alpha;
377
                result = PRIME * result + (and ? 1231 : 1237);
378
                result = PRIME * result + TransparencyRangeImpl.hashCode(blue);
379
                result = PRIME * result + TransparencyRangeImpl.hashCode(green);
380
                result = PRIME * result + TransparencyRangeImpl.hashCode(red);
381
                result = PRIME * result + ((strEntry == null) ? 0 : strEntry.hashCode());
382
                return result;
383
        }
384
        
385
        private static int hashCode(int[] array) {
386
                final int PRIME = 31;
387
                if (array == null)
388
                        return 0;
389
                int result = 1;
390
                for (int index = 0; index < array.length; index++) {
391
                        result = PRIME * result + array[index];
392
                }
393
                return result;
394
        }
395

    
396
        public boolean equals(Object obj) {
397
                if (this == obj)
398
                        return true;
399
                if (obj == null)
400
                        return false;
401
                if (getClass() != obj.getClass())
402
                        return false;
403
                final TransparencyRangeImpl other = (TransparencyRangeImpl) obj;
404
                if (alpha != other.alpha)
405
                        return false;
406
                if (and != other.and)
407
                        return false;
408
                if (!Arrays.equals(blue, other.blue))
409
                        return false;
410
                if (!Arrays.equals(green, other.green))
411
                        return false;
412
                if (!Arrays.equals(red, other.red))
413
                        return false;
414
                if (strEntry == null) {
415
                        if (other.strEntry != null)
416
                                return false;
417
                } else if (!strEntry.equals(other.strEntry))
418
                        return false;
419
                return true;
420
        }
421

    
422
        public void loadFromState(PersistentState state)
423
                        throws PersistenceException {
424
                strEntry = state.getString("strEntry");
425
                alpha = state.getInt("alpha");
426

    
427
                red = (int[])state.getIntArray("red");
428
                green = (int[])state.getIntArray("green");
429
                blue = (int[])state.getIntArray("blue");
430

    
431
                and = state.getBoolean("and");
432
        }
433

    
434
        public void saveToState(PersistentState state) throws PersistenceException {
435
                state.set("strEntry", strEntry);
436
                state.set("alpha", alpha);
437
                state.set("red", red);
438
                state.set("blue", blue);
439
                state.set("green", green);
440
                state.set("and", and);                
441
        }
442
        
443
        public static void registerPersistence() {
444
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
445
                DynStruct definition = manager.addDefinition(
446
                                TransparencyRangeImpl.class,
447
                                "TransparencyRange_Persistent",
448
                                "TransparencyRange Persistent definition",
449
                                null, 
450
                                null
451
                );
452
                definition.addDynFieldString("strEntry").setMandatory(false);
453
                definition.addDynFieldInt("alpha").setMandatory(false);
454
                definition.addDynFieldArray("red").setClassOfItems(int.class).setMandatory(false);
455
                definition.addDynFieldArray("blue").setClassOfItems(int.class).setMandatory(false);
456
                definition.addDynFieldArray("green").setClassOfItems(int.class).setMandatory(false);
457
                definition.addDynFieldBoolean("and").setMandatory(false);
458
        }
459
}