Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / QuantileIntervalGenerator.java @ 25766

History | View | Annotate | Download (7.96 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.fmap.rendering;
42

    
43
import java.util.ArrayList;
44

    
45
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
46
import com.hardcode.gdbms.engine.data.DataSource;
47
import com.hardcode.gdbms.engine.values.DoubleValue;
48
import com.hardcode.gdbms.engine.values.FloatValue;
49
import com.hardcode.gdbms.engine.values.IntValue;
50
import com.hardcode.gdbms.engine.values.LongValue;
51
import com.hardcode.gdbms.engine.values.ShortValue;
52
import com.hardcode.gdbms.engine.values.Value;
53

    
54

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

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

    
82
        /**
83
         * Genera los intervalos.
84
         *
85
         */
86
        public void generarIntervalos()
87
                throws ReadDriverException {
88
                ArrayList ordenadas = new ArrayList();
89
                ArrayList coincidencias = new ArrayList();
90
                int pos = sds.getFieldIndexByName(msFieldName);
91
                mdaValoresRuptura = new double[miNumIntervalosSolicitados - 1];
92
                mdaValInit = new double[miNumIntervalosSolicitados - 1];
93

    
94
                //int MARGEN = 5;
95
                for (int i = 0; i < sds.getRowCount(); i++) {
96
                        insertarEnVector(ordenadas, coincidencias, sds.getFieldValue(i, pos));
97
                }
98
                
99
                int index = 0;
100
                int posj = 0;
101

    
102
                for (int i = 1; i < miNumIntervalosSolicitados; i++) {
103
                        long x = (long) ((i * sds.getRowCount()) / miNumIntervalosSolicitados);
104

    
105
                        for (int j = posj; j < ordenadas.size(); j++) {
106
                                int auxcoin = ((Integer) coincidencias.get(j)).intValue();
107
                                index = index + auxcoin;
108

    
109
                                if (x <= index) {
110
                                        mdaValoresRuptura[i - 1] = getValue((Value) ordenadas.get(j));
111

    
112
                                        /*index = (int) ((x + (auxcoin / miNumIntervalosSolicitados)) -
113
                                           1);
114
                                         */
115
                                        posj = j + 1;
116

    
117
                                        if (posj < ordenadas.size()) {
118
                                                mdaValInit[i - 1] = getValue((Value) ordenadas.get(posj));
119
                                        } else {
120
                                                mdaValInit[i - 1] = getValue((Value) ordenadas.get(j));
121
                                        }
122

    
123
                                        num++;
124

    
125
                                        break;
126
                                }
127
                        }
128

    
129
                        //double value=getValue(sds.getFieldValue(x,pos));
130
                }
131

    
132
                //}
133
        }
134

    
135
        /**
136
         * Esta funci?n busca en el vector de datos la posici?n que le corresponde
137
         * al valor almacenado en vdValor y devuelve dicha posici?n en
138
         * vdValorAInsertar. Para hallar la posici?n se realiza una b?squeda
139
         * binaria. Si se trata de un elemento que ya est? en el vector devolvemos
140
         * el ?ndice que le corresponde en rlIndiceCorrespondiente y false en
141
         * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
142
         * insertar... devolvemos el ?ndice en el que ir?a y True en
143
         * rbNuevoElemento En caso de que ocurra alg?n error devuelve false
144
         *
145
         * @param rVectorDatos ArrayList con los datos.
146
         * @param coincidencia ?ndice.
147
         * @param vdValorAInsertar Valor a insertar.
148
         */
149
        protected void insertarEnVector(ArrayList rVectorDatos,
150
                ArrayList coincidencia, Value vdValorAInsertar) {
151
                int llIndiceIzq;
152
                int llIndiceDer;
153
                int llMedio;
154
                int indice = -1;
155
                double ldValorComparacion;
156
                double valorAInsertar = getValue(vdValorAInsertar);
157

    
158
                if (rVectorDatos.size() == 0) {
159
                        rVectorDatos.add(vdValorAInsertar);
160
                        coincidencia.add(new Integer(1));
161

    
162
                        return;
163
                }
164

    
165
                llIndiceIzq = 0;
166
                llIndiceDer = rVectorDatos.size() - 1;
167
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera!
168

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

    
173
                        //'Si el valor a insertar es mayor que el valor de comparaci?n...
174
                        if (valorAInsertar > ldValorComparacion) {
175
                                //      'La zona de b?squeda queda restringida a la parte de la derecha
176
                                llIndiceIzq = llMedio + 1;
177
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
178

    
179
                                //    'Si el valor a insertar es menor que el valor de comparaci?n...
180
                        } else if (valorAInsertar < ldValorComparacion) {
181
                                //          'La zona de b?squeda queda restringida a la parte de la derecha
182
                                llIndiceDer = llMedio - 1;
183
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
184

    
185
                                //        'Si el valor de comparaci?n coincide con el valor a insertar
186
                        } else if (valorAInsertar == ldValorComparacion) {
187
                                indice = llMedio;
188

    
189
                                int index = rVectorDatos.indexOf(vdValorAInsertar);
190
                                int coin = ((Integer) coincidencia.get(index)).intValue() + 1;
191
                                coincidencia.remove(index);
192
                                coincidencia.add(index, new Integer(coin));
193

    
194
                                return;
195
                        }
196
                }
197

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

    
207
                if (valorAInsertar > ldValorComparacion) {
208
                        indice = llMedio + 1;
209
                } else {
210
                        indice = llMedio;
211
                }
212

    
213
                rVectorDatos.add(indice, vdValorAInsertar);
214
                coincidencia.add(indice, new Integer(1));
215
        }
216

    
217
        /**
218
         * Devuelve el valor en un double del Value que se pasa como par?metro.
219
         *
220
         * @param value Value.
221
         *
222
         * @return valor.
223
         */
224
        protected double getValue(Value value) {
225
                if (value instanceof IntValue) {
226
                        return ((IntValue) value).intValue();
227
                } else if (value instanceof LongValue) {
228
                        return ((LongValue) value).longValue();
229
                } else if (value instanceof FloatValue) {
230
                        return ((FloatValue) value).floatValue();
231
                } else if (value instanceof ShortValue) {
232
                        return ((ShortValue) value).shortValue();
233
                } else if (value instanceof DoubleValue){
234
                        return ((DoubleValue) value).doubleValue();
235
                }
236
                return 0;
237

    
238
        }
239

    
240
        /**
241
         * Devuelve el valor del punto de ruptura seg?n el ?ndice que se pasa como
242
         * par?metro.
243
         *
244
         * @param index ?ndice del punto de ruptura.
245
         *
246
         * @return valor.
247
         */
248
        public double getValRuptura(int index) {
249
                return mdaValoresRuptura[index];
250
        }
251

    
252
        /**
253
         * Devuelve el valor inicial de cada intervalo.
254
         *
255
         * @param index ?ndice del intervalo.
256
         *
257
         * @return valor del intervalo.
258
         */
259
        public double getValInit(int index) {
260
                return mdaValInit[index];
261
        }
262

    
263
        /**
264
         * Devuelve el n?mero de intervalos que se han generado.
265
         *
266
         * @return N?mero de intervalos generados.
267
         */
268
        public int getNumIntervalGen() {
269
                return num + 1;
270
        }
271
}