Statistics
| Revision:

root / branches / gvSIG_03_SLD / applications / appgvSIG / src / com / iver / cit / gvsig / gui / thememanager / legendmanager / panels / QuantileIntervalGenerator.java @ 2102

History | View | Annotate | Download (9.08 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 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
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.gui.thememanager.legendmanager.panels;
42

    
43
import com.hardcode.gdbms.engine.values.DoubleValue;
44
import com.hardcode.gdbms.engine.values.FloatValue;
45
import com.hardcode.gdbms.engine.values.IntValue;
46
import com.hardcode.gdbms.engine.values.LongValue;
47
import com.hardcode.gdbms.engine.values.ShortValue;
48
import com.hardcode.gdbms.engine.values.Value;
49

    
50
import com.iver.cit.gvsig.fmap.DriverException;
51
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
52
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
53

    
54
import java.util.ArrayList;
55

    
56

    
57
/**
58
 * Calcula los intervalos en funci?n del n?mero de intervalos que se pidan.
59
 *
60
 * @author Vicente Caballero Navarro
61
 */
62
public class QuantileIntervalGenerator {
63
        private AlphanumericData mLayer;
64
        private String msFieldName;
65
        private int miNumIntervalosSolicitados;
66
        private double[] mdaValoresRuptura;
67
        private double[] mdaValInit;
68
        private int num = 0;
69

    
70
        /**
71
         * Crea un nuevo QuantileIntervalGenerator.
72
         *
73
         * @param layer DOCUMENT ME!
74
         * @param field DOCUMENT ME!
75
         * @param numIntervals DOCUMENT ME!
76
         */
77
        public QuantileIntervalGenerator(AlphanumericData layer, String field,
78
                int numIntervals) {
79
                mLayer = layer;
80
                msFieldName = field;
81
                miNumIntervalosSolicitados = numIntervals;
82
        }
83

    
84
        /**
85
         * Genera los intervalos.
86
         *
87
         * @throws DriverException
88
         * @throws com.hardcode.gdbms.engine.data.driver.DriverException
89
         */
90
        public void generarIntervalos()
91
                throws DriverException, 
92
                        com.hardcode.gdbms.engine.data.driver.DriverException {
93
                SelectableDataSource sds = mLayer.getRecordset();
94
                ArrayList ordenadas = new ArrayList();
95
                ArrayList coincidencias = new ArrayList();
96
                int pos = sds.getFieldIndexByName(msFieldName);
97
                mdaValoresRuptura = new double[miNumIntervalosSolicitados - 1];
98
                mdaValInit = new double[miNumIntervalosSolicitados - 1];
99

    
100
                //int MARGEN = 5;
101
                for (int i = 0; i < sds.getRowCount(); i++) {
102
                        insertarEnVector(ordenadas, coincidencias, sds.getFieldValue(i, pos));
103
                }
104

    
105
                int numRowQuantile = (int) ((sds.getRowCount() / miNumIntervalosSolicitados) -
106
                        0.5);
107

    
108
                //for (int i=1;i<miNumIntervalosSolicitados;i++){
109
                int sum = 0;
110
                num = 0;
111

    
112
                /*for (int j=0;j<ordenadas.size();j++){
113
                   int auxsum=((Integer)coincidencias.get(j)).intValue();
114
                   if ((sum+auxsum)>=numRowQuantile){
115
                           if ((sum+auxsum)<(numRowQuantile+MARGEN) ){
116
                                   mdaValoresRuptura[num]=getValue((Value)ordenadas.get(j));
117
                                   sum=0;
118
                                   //num++;
119
                           }else{
120
                                   if (num<miNumIntervalosSolicitados){
121
                                   mdaValoresRuptura[num]=getValue((Value)ordenadas.get(j-1));
122
                                   sum=auxsum;
123
                                   }else{
124
                                           return;
125
                                   }
126
                                   //num++;
127
                           }
128
                           num++;
129
                   }else{
130
                           sum=sum+auxsum;
131
                
132
                   }
133
                   //num++;
134
                
135
                   }*/
136
                int index = 0;
137
                int posj = 0;
138

    
139
                for (int i = 1; i < miNumIntervalosSolicitados; i++) {
140
                        long x = (long) ((i * sds.getRowCount()) / miNumIntervalosSolicitados);
141

    
142
                        for (int j = posj; j < ordenadas.size(); j++) {
143
                                int auxcoin = ((Integer) coincidencias.get(j)).intValue();
144
                                index = index + auxcoin;
145

    
146
                                if (x <= index) {
147
                                        mdaValoresRuptura[i - 1] = getValue((Value) ordenadas.get(j));
148

    
149
                                        /*index = (int) ((x + (auxcoin / miNumIntervalosSolicitados)) -
150
                                           1);
151
                                         */
152
                                        posj = j + 1;
153

    
154
                                        if (posj < ordenadas.size()) {
155
                                                mdaValInit[i - 1] = getValue((Value) ordenadas.get(posj));
156
                                        } else {
157
                                                mdaValInit[i - 1] = getValue((Value) ordenadas.get(j));
158
                                        }
159

    
160
                                        num++;
161

    
162
                                        break;
163
                                }
164
                        }
165

    
166
                        //double value=getValue(sds.getFieldValue(x,pos));
167
                }
168

    
169
                //}
170
        }
171

    
172
        /**
173
         * Esta funci?n busca en el vector de datos la posici?n que le corresponde
174
         * al valor almacenado en vdValor y devuelve dicha posici?n en
175
         * vdValorAInsertar. Para hallar la posici?n se realiza una b?squeda
176
         * binaria. Si se trata de un elemento que ya est? en el vector devolvemos
177
         * el ?ndice que le corresponde en rlIndiceCorrespondiente y false en
178
         * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
179
         * insertar... devolvemos el ?ndice en el que ir?a y True en
180
         * rbNuevoElemento En caso de que ocurra alg?n error devuelve false
181
         *
182
         * @param rVectorDatos ArrayList con los datos.
183
         * @param coincidencia ?ndice.
184
         * @param vdValorAInsertar Valor a insertar.
185
         */
186
        private void insertarEnVector(ArrayList rVectorDatos,
187
                ArrayList coincidencia, Value vdValorAInsertar) {
188
                int llIndiceIzq;
189
                int llIndiceDer;
190
                int llMedio;
191
                int indice = -1;
192
                double ldValorComparacion;
193
                double valorAInsertar = getValue(vdValorAInsertar);
194

    
195
                if (rVectorDatos.size() == 0) {
196
                        rVectorDatos.add(vdValorAInsertar);
197
                        coincidencia.add(new Integer(1));
198

    
199
                        return;
200
                }
201

    
202
                llIndiceIzq = 0;
203
                llIndiceDer = rVectorDatos.size() - 1;
204
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera!
205

    
206
                while (llIndiceIzq <= llIndiceDer) {
207
                        //'Coger el valor situado en la mitad de la zona de b?squeda como valor de comparaci?n
208
                        ldValorComparacion = getValue((Value) rVectorDatos.get(llMedio));
209

    
210
                        //'Si el valor a insertar es mayor que el valor de comparaci?n...
211
                        if (valorAInsertar > ldValorComparacion) {
212
                                //      'La zona de b?squeda queda restringida a la parte de la derecha
213
                                llIndiceIzq = llMedio + 1;
214
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
215

    
216
                                //    'Si el valor a insertar es menor que el valor de comparaci?n...
217
                        } else if (valorAInsertar < ldValorComparacion) {
218
                                //          'La zona de b?squeda queda restringida a la parte de la derecha
219
                                llIndiceDer = llMedio - 1;
220
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
221

    
222
                                //        'Si el valor de comparaci?n coincide con el valor a insertar
223
                        } else if (valorAInsertar == ldValorComparacion) {
224
                                indice = llMedio;
225

    
226
                                int index = rVectorDatos.indexOf(vdValorAInsertar);
227
                                int coin = ((Integer) coincidencia.get(index)).intValue() + 1;
228
                                coincidencia.remove(index);
229
                                coincidencia.add(index, new Integer(coin));
230

    
231
                                return;
232
                        }
233
                }
234

    
235
                //  'Nota:
236
                //  'En este caso (cuando en rbNuevoElemento se devuelve True) lo que hay que hacer al salir de esta funci?n
237
                //  'es a?adir un nuevo elemento al vector y desplazar todos los valores correspondientes a partir de rlIndiceCorrespondiente
238
                //  '?D?nde va el nuevo elemento?
239
                //  'El ?ltimo sitio estudiado viene dado por el valor de llMedio.
240
                //  'Si el valor a insertar es menor que el valor almacenado en la posici?n llMedio, el nuevo valor deber? ir a su izquierda.
241
                //  'Si fuera mayor deber?a ir a su derecha.
242
                ldValorComparacion = getValue((Value) rVectorDatos.get(llMedio));
243

    
244
                if (valorAInsertar > ldValorComparacion) {
245
                        indice = llMedio + 1;
246
                } else {
247
                        indice = llMedio;
248
                }
249

    
250
                rVectorDatos.add(indice, vdValorAInsertar);
251
                coincidencia.add(indice, new Integer(1));
252
        }
253

    
254
        /**
255
         * Devuelve el valor en un double del Value que se pasa como par?metro.
256
         *
257
         * @param value Value.
258
         *
259
         * @return valor.
260
         */
261
        private double getValue(Value value) {
262
                if (value instanceof IntValue) {
263
                        return ((IntValue) value).intValue();
264
                } else if (value instanceof LongValue) {
265
                        return ((LongValue) value).longValue();
266
                } else if (value instanceof FloatValue) {
267
                        return ((FloatValue) value).floatValue();
268
                } else if (value instanceof ShortValue) {
269
                        return ((ShortValue) value).shortValue();
270
                }
271

    
272
                return ((DoubleValue) value).doubleValue();
273
        }
274

    
275
        /**
276
         * Devuelve el valor del punto de ruptura seg?n el ?ndice que se pasa como
277
         * par?metro.
278
         *
279
         * @param index ?ndice del punto de ruptura.
280
         *
281
         * @return valor.
282
         */
283
        public double getValRuptura(int index) {
284
                return mdaValoresRuptura[index];
285
        }
286

    
287
        /**
288
         * Devuelve el valor inicial de cada intervalo.
289
         *
290
         * @param index ?ndice del intervalo.
291
         *
292
         * @return valor del intervalo.
293
         */
294
        public double getValInit(int index) {
295
                return mdaValInit[index];
296
        }
297

    
298
        /**
299
         * Devuelve el n?mero de intervalos que se han generado.
300
         *
301
         * @return N?mero de intervalos generados.
302
         */
303
        public int getNumIntervalGen() {
304
                return num + 1;
305
        }
306
}