Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / datastruct / TransparencyRange.java @ 17782

History | View | Annotate | Download (11.4 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.datastruct;
20

    
21
import java.io.IOException;
22
import java.util.Arrays;
23

    
24
import org.gvsig.raster.dataset.RasterDataset;
25
/**
26
 * Clase que representa a un conjunto de pixeles con transparencia. Incluye los
27
 * rangos de transparencia para cada banda, la cadena que va en la lista y la
28
 * operaci?n que se realiza entre ellos. Un And significa que ser?n
29
 * transparentes todos los pixeles que cumplan con R con G y con B. Un Or
30
 * significar? que tendr?n transparencia todos los pixeles que cumplan con R con
31
 * G o con B.
32
 *
33
 * @author Nacho Brodin (nachobrodin@gmail.com)
34
 */
35
public class TransparencyRange implements Cloneable {
36
        private String  strEntry = null;
37
        private int[]   red      = null;
38
        private int[]   green    = null;
39
        private int[]   blue     = null;
40
        private boolean and      = true;
41
        private int     alpha    = 0;
42

    
43
        /**
44
         * Constructor
45
         */
46
        public TransparencyRange() {
47
        }
48

    
49
        /**
50
         * Crea un objeto TransparencyRange a partir de una cadena bien formada
51
         * @param value cadena bien formada que representa un intervalo
52
         */
53
        public TransparencyRange(String value) {
54
                try {
55
                        red = new int[2];
56
                        green = new int[2];
57
                        blue = new int[2];
58
                        and = TransparencyRange.stringToInterval(value, red, green, blue);
59
                        strEntry = value;
60
                } catch (IOException e) {
61
                        // Cadena mal formada
62
                }
63
        }
64

    
65
        
66
        /**
67
         * Obtiene la operaci?n  utilizada
68
         * @param and Si es true significa que se usa un AND y false implica
69
         * que se usa un OR
70
         */
71
        public boolean isAnd() {
72
                return and;
73
        }
74

    
75
        /**
76
         * Asigna la operaci?n AND como la utilizada
77
         * @param and booleano que si est? a true significa que el la operaci?n
78
         * AND es la utilizada como operaci?n.
79
         */
80
        public void setAnd(boolean and) {
81
                this.and = and;
82
        }
83

    
84
        /**
85
         * Obtiene el intervalo de valores correspondiente a la banda del azul
86
         * @return Array bidimensional de enteros correspondiente a la banda del azul
87
         */
88
        public int[] getBlue() {
89
                return blue;
90
        }
91

    
92
        /**
93
         * Asigna los intervalos de valores correspondientes a las bandas del
94
         * rojo, azul y verde
95
         * @param red Array bidimensional de enteros correspondiente a la banda del rojo
96
         * @param green Array bidimensional de enteros correspondiente a la banda del verde
97
         * @param blue Array bidimensional de enteros correspondiente a la banda del azul
98
         */
99
        public void setRGB(int[] red, int[] green, int[] blue) {
100
                this.red = red;
101
                this.green = green;
102
                this.blue = blue;
103
        }
104

    
105
        /**
106
         * Asigna el intervalo de valores correspondiente a la banda del azul
107
         * @param blue Array bidimensional de enteros correspondiente a la banda del azul
108
         */
109
        public void setBlue(int[] blue) {
110
                this.blue = blue;
111
        }
112

    
113
        /**
114
         * Obtiene el intervalo de valores correspondiente a la banda del verde
115
         * @return Array bidimensional de enteros correspondiente a la banda del verde
116
         */
117
        public int[] getGreen() {
118
                return green;
119
        }
120

    
121
        /**
122
         * Asigna el intervalo de valores correspondiente a la banda del verde
123
         * @param green Array bidimensional de enteros correspondiente a la banda del verde
124
         */
125
        public void setGreen(int[] green) {
126
                this.green = green;
127
        }
128

    
129
        /**
130
         * Obtiene el intervalo de valores correspondiente a la banda del rojo
131
         * @return Array bidimensional de enteros correspondiente a la banda del rojo
132
         */
133
        public int[] getRed() {
134
                return red;
135
        }
136

    
137
        /**
138
         * Asigna el intervalo de valores correspondiente a la banda del rojo
139
         * @param red Array bidimensional de enteros correspondiente a la banda del rojo
140
         */
141
        public void setRed(int[] red) {
142
                this.red = red;
143
        }
144

    
145
        /**
146
         * Obtiene la cadena que representa una entrada en la tabla.
147
         * @return Cadena que representa una entrada en la tabla
148
         */
149
        public String getStrEntry() {
150
                return strEntry;
151
        }
152

    
153
        /**
154
         * Asigna la cadena que representa una entrada en la tabla.
155
         * @param strEntry Cadena que representa una entrada en la tabla.
156
         */
157
        public void setStrEntry(String strEntry) {
158
                this.strEntry = strEntry;
159
        }
160

    
161

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

    
230
                // Si el analisis es correcto parseamos
231
                if ((status == 1 || status == 3) && ((countAnd == 2 && countOr == 0) || (countAnd == 0 && countOr == 2))) {
232
                        String[] s = values.split(" & ");
233
                        if (s.length < 3) {
234
                                s = values.split(" \\| ");
235
                                and = false;
236
                        }
237
                        ;
238
                        String[] val = s[0].split(":");
239
                        try {
240
                                r[0] = Integer.parseInt(val[0]);
241
                                if (val.length == 2)
242
                                        r[1] = Integer.parseInt(val[1]);
243
                                else
244
                                        r[1] = Integer.parseInt(val[0]);
245
                        } catch (NumberFormatException e) {
246
                                r[0] = -1;
247
                                r[1] = -1;
248
                        }
249

    
250
                        val = s[1].split(":");
251
                        try {
252
                                g[0] = Integer.parseInt(val[0]);
253
                                if (val.length == 2)
254
                                        g[1] = Integer.parseInt(val[1]);
255
                                else
256
                                        g[1] = Integer.parseInt(val[0]);
257
                        } catch (NumberFormatException e) {
258
                                g[0] = -1;
259
                                g[1] = -1;
260
                        }
261

    
262
                        val = s[2].split(":");
263
                        try {
264
                                b[0] = Integer.parseInt(val[0]);
265
                                if (val.length == 2)
266
                                        b[1] = Integer.parseInt(val[1]);
267
                                else
268
                                        b[1] = Integer.parseInt(val[0]);
269
                        } catch (NumberFormatException e) {
270
                                b[0] = -1;
271
                                b[1] = -1;
272
                        }
273
                } else
274
                        throw new IOException("Error en la cadena de entrada ");
275

    
276
                return and;
277
        }
278

    
279
        /**
280
         * Carga la cadena StrEntry leyendo los valores en los vectores que representa los intervalos.
281
         */
282
        public void loadStrEntryFromValues(){
283
                String separator = " | ";
284
                if (and)
285
                        separator = " & ";
286
                strEntry = String.valueOf(red[0] + separator+ green[0] + separator + blue[0]);
287
        }
288

    
289
        /**
290
         * Obtiene el alpha asociado al rango. Por defecto es de 0, es decir
291
         * totalmente transparente pero puede asociarsele un valor distinto
292
         * @return Alpha asociado
293
         */
294
        public int getAlpha() {
295
                return alpha;
296
        }
297

    
298
        /**
299
         * Asigna el alpha asociado al rango. Por defecto es de 0, es decir
300
         * totalmente transparente pero puede asociarsele un valor distinto
301
         * @param alpha asociado
302
         */
303
        public void setAlpha(int alpha) {
304
                this.alpha = alpha;
305
        }
306

    
307
        /**
308
         * Realiza la uni?n entre el intervalo actual y el pasado por par?metro
309
         * @param interval intervalo pasado
310
         * @param rgb
311
         * @return union de intervalos
312
         */
313
        public int[] union(int[] interval, int rgb) {
314
                switch (rgb) {
315
                        case RasterDataset.RED_BAND:
316
                                if ((red[1] >= interval[0] && red[0] <= interval[0]) || (red[0] <= interval[1] && red[0] >= interval[0]))
317
                                        return new int[] { Math.min(red[0], interval[0]), Math.max(red[1], interval[1]) };
318
                        case RasterDataset.GREEN_BAND:
319
                                if ((green[1] >= interval[0] && green[0] <= interval[0]) || (green[0] <= interval[1] && green[0] >= interval[0]))
320
                                        return new int[] { Math.min(green[0], interval[0]), Math.max(green[1], interval[1]) };
321
                        case RasterDataset.BLUE_BAND:
322
                                if ((blue[1] >= interval[0] && blue[0] <= interval[0]) || (blue[0] <= interval[1] && blue[0] >= interval[0]))
323
                                        return new int[] { Math.min(blue[0], interval[0]), Math.max(blue[1], interval[1]) };
324
                }
325
                return null;
326
        }
327

    
328
        /**
329
         * Muestra los datos del objeto para depuraci?n.
330
         */
331
        public void show(){
332
                if (getRed() != null)
333
                        System.out.println(getRed()[0] + " " + getRed()[1]);
334
                if (getGreen() != null)
335
                        System.out.println(getGreen()[0] + " " + getGreen()[1]);
336
                if (getBlue() != null)
337
                        System.out.println(getBlue()[0] + " " + getBlue()[1]);
338
                System.out.println(isAnd());
339
                System.out.println(getStrEntry());
340
                System.out.println("--------------------");
341
        }
342

    
343
        /*
344
         * (non-Javadoc)
345
         * @see java.lang.Object#clone()
346
         */
347
        public Object clone() {
348
                TransparencyRange clone = null;
349
                try {
350
                        clone = (TransparencyRange) super.clone();
351
                } catch (CloneNotSupportedException e) {
352
                }
353

    
354
                if (strEntry != null)
355
                        clone.strEntry = new String(strEntry);
356

    
357
                if (red != null)
358
                        clone.red = (int[]) red.clone();
359

    
360
                if (green != null)
361
                        clone.green = (int[]) green.clone();
362

    
363
                if (blue != null)
364
                        clone.blue = (int[]) blue.clone();
365

    
366
                return clone;
367
        }
368

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

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