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

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

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

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

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

    
285
                return and;
286
        }
287

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

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

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

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

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

    
352
        /*
353
         * (non-Javadoc)
354
         * @see java.lang.Object#clone()
355
         */
356
        public Object clone() {
357
                TransparencyRangeImpl clone = null;
358
                try {
359
                        clone = (TransparencyRangeImpl) super.clone();
360
                } catch (CloneNotSupportedException e) {
361
                }
362

    
363
                if (strEntry != null)
364
                        clone.strEntry = new String(strEntry);
365

    
366
                if (red != null)
367
                        clone.red = (int[]) red.clone();
368

    
369
                if (green != null)
370
                        clone.green = (int[]) green.clone();
371

    
372
                if (blue != null)
373
                        clone.blue = (int[]) blue.clone();
374

    
375
                return clone;
376
        }
377

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

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

    
427
        /*
428
         * (non-Javadoc)
429
         * @see org.gvsig.tools.persistence.Persistent#loadFromState(org.gvsig.tools.persistence.PersistentState)
430
         */
431
        public void loadFromState(PersistentState state)
432
                        throws PersistenceException {
433
                strEntry = state.getString("strEntry");
434
                alpha = state.getInt("alpha");
435

    
436
                red = (int[])state.getIntArray("red");
437
                green = (int[])state.getIntArray("green");
438
                blue = (int[])state.getIntArray("blue");
439

    
440
                and = state.getBoolean("and");
441
        }
442

    
443
        /*
444
         * (non-Javadoc)
445
         * @see org.gvsig.tools.persistence.Persistent#saveToState(org.gvsig.tools.persistence.PersistentState)
446
         */
447
        public void saveToState(PersistentState state) throws PersistenceException {
448
                state.set("strEntry", strEntry);
449
                state.set("alpha", alpha);
450
                state.set("red", red);
451
                state.set("blue", blue);
452
                state.set("green", green);
453
                state.set("and", and);                
454
        }
455
        
456
        public static void registerPersistence() {
457
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
458
                DynStruct definition = manager.addDefinition(
459
                                TransparencyRangeImpl.class,
460
                                "TransparencyRange_Persistent",
461
                                "TransparencyRange Persistent definition",
462
                                null, 
463
                                null
464
                );
465
                definition.addDynFieldString("strEntry").setMandatory(false);
466
                definition.addDynFieldInt("alpha").setMandatory(false);
467
                definition.addDynFieldArray("red").setClassOfItems(int.class).setMandatory(false);
468
                definition.addDynFieldArray("blue").setClassOfItems(int.class).setMandatory(false);
469
                definition.addDynFieldArray("green").setClassOfItems(int.class).setMandatory(false);
470
                definition.addDynFieldBoolean("and").setMandatory(false);
471
        }
472
}