Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / mapcontext / rendering / legend / QuantileIntervalGenerator.java @ 21144

History | View | Annotate | Download (7.72 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 org.gvsig.fmap.mapcontext.rendering.legend;
42

    
43
import java.util.ArrayList;
44
import java.util.Iterator;
45

    
46
import org.gvsig.data.ReadException;
47
import org.gvsig.data.vectorial.Feature;
48
import org.gvsig.data.vectorial.FeatureStore;
49
import org.gvsig.data.vectorial.FeatureType;
50

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

    
65
        /**
66
         * Crea un nuevo QuantileIntervalGenerator.
67
         *
68
         * @param layer DOCUMENT ME!
69
         * @param field DOCUMENT ME!
70
         * @param numIntervals DOCUMENT ME!
71
         */
72
        public QuantileIntervalGenerator(FeatureStore fs, String field,
73
                int numIntervals) {
74
                featureStore = fs;
75
                msFieldName = field;
76
                miNumIntervalosSolicitados = numIntervals;
77
        }
78

    
79
        /**
80
         * Genera los intervalos.
81
         *
82
         */
83
        public void generarIntervalos()
84
                throws ReadException {
85
                ArrayList ordenadas = new ArrayList();
86
                ArrayList coincidencias = new ArrayList();
87
                int pos = ((FeatureType)featureStore.getFeatureTypes().get(0)).getFieldIndex(msFieldName);
88
                mdaValoresRuptura = new double[miNumIntervalosSolicitados - 1];
89
                mdaValInit = new double[miNumIntervalosSolicitados - 1];
90

    
91
                Iterator iterator=featureStore.getDataCollection(new String[]{msFieldName},null,null).iterator();
92
                long rowCount=0;
93
                while (iterator.hasNext()) {
94
                        Feature feature = (Feature) iterator.next();
95
                        insertarEnVector(ordenadas, coincidencias, feature.get(0));//sds.getFieldValue(i, pos));
96
                        rowCount++;
97
                }
98
                //int MARGEN = 5;
99
//                for (int i = 0; i < sds.getRowCount(); i++) {
100
//                        insertarEnVector(ordenadas, coincidencias, sds.getFieldValue(i, pos));
101
//                }
102

    
103
                int index = 0;
104
                int posj = 0;
105

    
106
                for (int i = 1; i < miNumIntervalosSolicitados; i++) {
107
                        long x = (long) ((i * rowCount) / miNumIntervalosSolicitados);
108

    
109
                        for (int j = posj; j < ordenadas.size(); j++) {
110
                                int auxcoin = ((Integer) coincidencias.get(j)).intValue();
111
                                index = index + auxcoin;
112

    
113
                                if (x <= index) {
114
                                        mdaValoresRuptura[i - 1] = getValue(ordenadas.get(j));
115

    
116
                                        /*index = (int) ((x + (auxcoin / miNumIntervalosSolicitados)) -
117
                                           1);
118
                                         */
119
                                        posj = j + 1;
120

    
121
                                        if (posj < ordenadas.size()) {
122
                                                mdaValInit[i - 1] = getValue(ordenadas.get(posj));
123
                                        } else {
124
                                                mdaValInit[i - 1] = getValue(ordenadas.get(j));
125
                                        }
126

    
127
                                        num++;
128

    
129
                                        break;
130
                                }
131
                        }
132

    
133
                        //double value=getValue(sds.getFieldValue(x,pos));
134
                }
135

    
136
                //}
137
        }
138

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

    
162
                if (rVectorDatos.size() == 0) {
163
                        rVectorDatos.add(vdValorAInsertar);
164
                        coincidencia.add(new Integer(1));
165

    
166
                        return;
167
                }
168

    
169
                llIndiceIzq = 0;
170
                llIndiceDer = rVectorDatos.size() - 1;
171
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera!
172

    
173
                while (llIndiceIzq <= llIndiceDer) {
174
                        //'Coger el valor situado en la mitad de la zona de b?squeda como valor de comparaci?n
175
                        ldValorComparacion = getValue( rVectorDatos.get(llMedio));
176

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

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

    
189
                                //        'Si el valor de comparaci?n coincide con el valor a insertar
190
                        } else if (valorAInsertar == ldValorComparacion) {
191
                                indice = llMedio;
192

    
193
                                int index = rVectorDatos.indexOf(vdValorAInsertar);
194
                                int coin = ((Integer) coincidencia.get(index)).intValue() + 1;
195
                                coincidencia.remove(index);
196
                                coincidencia.add(index, new Integer(coin));
197

    
198
                                return;
199
                        }
200
                }
201

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

    
211
                if (valorAInsertar > ldValorComparacion) {
212
                        indice = llMedio + 1;
213
                } else {
214
                        indice = llMedio;
215
                }
216

    
217
                rVectorDatos.add(indice, vdValorAInsertar);
218
                coincidencia.add(indice, new Integer(1));
219
        }
220

    
221
        /**
222
         * Devuelve el valor en un double del Value que se pasa como par?metro.
223
         *
224
         * @param value Value.
225
         *
226
         * @return valor.
227
         */
228
        private double getValue(Object value) {
229
                if (value instanceof Number) {
230
                        return ((Number) value).doubleValue();
231
                }
232
                return 0;
233

    
234
        }
235

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

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

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