Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / QuantileIntervalGenerator.java @ 7304

History | View | Annotate | Download (9.14 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.project.documents.view.legend;
42

    
43
import java.util.ArrayList;
44

    
45
import com.hardcode.gdbms.engine.values.DoubleValue;
46
import com.hardcode.gdbms.engine.values.FloatValue;
47
import com.hardcode.gdbms.engine.values.IntValue;
48
import com.hardcode.gdbms.engine.values.LongValue;
49
import com.hardcode.gdbms.engine.values.ShortValue;
50
import com.hardcode.gdbms.engine.values.Value;
51
import com.iver.cit.gvsig.fmap.DriverException;
52
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
53
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
54

    
55

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

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

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

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

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

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

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

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

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

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

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

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

    
159
                                        num++;
160

    
161
                                        break;
162
                                }
163
                        }
164

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

    
168
                //}
169
        }
170

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

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

    
198
                        return;
199
                }
200

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

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

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

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

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

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

    
230
                                return;
231
                        }
232
                }
233

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

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

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

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

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

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

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