Statistics
| Revision:

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

History | View | Annotate | Download (8.6 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 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

    
98
                //int MARGEN = 5;
99

    
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
                                        /*index = (int) ((x + (auxcoin / miNumIntervalosSolicitados)) -
148
                                                1);
149
                                        */posj = j + 1;
150
                                        num++;
151

    
152
                                        break;
153
                                }
154
                        }
155

    
156
                        //double value=getValue(sds.getFieldValue(x,pos));
157
                }
158

    
159
                //}
160
        }
161

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

    
185
                if (rVectorDatos.size() == 0) {
186
                        rVectorDatos.add(vdValorAInsertar);
187
                        coincidencia.add(new Integer(1));
188

    
189
                        return;
190
                }
191

    
192
                llIndiceIzq = 0;
193
                llIndiceDer = rVectorDatos.size() - 1;
194
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera!
195

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

    
200
                        //'Si el valor a insertar es mayor que el valor de comparaci?n...
201
                        if (valorAInsertar > ldValorComparacion) {
202
                                //      'La zona de b?squeda queda restringida a la parte de la derecha
203
                                llIndiceIzq = llMedio + 1;
204
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
205

    
206
                                //    'Si el valor a insertar es menor que el valor de comparaci?n...
207
                        } else if (valorAInsertar < ldValorComparacion) {
208
                                //          'La zona de b?squeda queda restringida a la parte de la derecha
209
                                llIndiceDer = llMedio - 1;
210
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
211

    
212
                                //        'Si el valor de comparaci?n coincide con el valor a insertar
213
                        } else if (valorAInsertar == ldValorComparacion) {
214
                                indice = llMedio;
215

    
216
                                int index = rVectorDatos.indexOf(vdValorAInsertar);
217
                                int coin = ((Integer) coincidencia.get(index)).intValue() + 1;
218
                                coincidencia.remove(index);
219
                                coincidencia.add(index, new Integer(coin));
220

    
221
                                return;
222
                        }
223
                }
224

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

    
234
                if (valorAInsertar > ldValorComparacion) {
235
                        indice = llMedio + 1;
236
                } else {
237
                        indice = llMedio;
238
                }
239

    
240
                rVectorDatos.add(indice, vdValorAInsertar);
241
                coincidencia.add(indice, new Integer(1));
242
        }
243

    
244
        /**
245
         * Devuelve el valor en un double del Value que se pasa como par?metro.
246
         *
247
         * @param value Value.
248
         *
249
         * @return valor.
250
         */
251
        private double getValue(Value value) {
252
                if (value instanceof IntValue) {
253
                        return ((IntValue) value).intValue();
254
                } else if (value instanceof LongValue) {
255
                        return ((LongValue) value).longValue();
256
                } else if (value instanceof FloatValue) {
257
                        return ((FloatValue) value).floatValue();
258
                } else if (value instanceof ShortValue) {
259
                        return ((ShortValue) value).shortValue();
260
                }
261

    
262
                return ((DoubleValue) value).doubleValue();
263
        }
264

    
265
        /**
266
         * Devuelve el valor del punto de ruptura seg?n el ?ndice que se pasa como
267
         * par?metro.
268
         *
269
         * @param index ?ndice del punto de ruptura.
270
         *
271
         * @return valor.
272
         */
273
        public double getNumRuptura(int index) {
274
                return mdaValoresRuptura[index];
275
        }
276

    
277
        /**
278
         * Devuelve el n?mero de intervalos que se han generado.
279
         *
280
         * @return N?mero de intervalos generados.
281
         */
282
        public int getNumIntervalGen() {
283
                return num + 1;
284
        }
285
}