Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / impl / QuantileIntervalGenerator.java @ 40560

History | View | Annotate | Download (8.29 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl;
25

    
26
import java.util.ArrayList;
27
import java.util.List;
28

    
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.tools.dispose.DisposableIterator;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.dal.feature.FeatureQuery;
33
import org.gvsig.fmap.dal.feature.FeatureSet;
34
import org.gvsig.fmap.dal.feature.FeatureStore;
35

    
36
/**
37
 * Calcula los intervalos en funci?n del n?mero de intervalos que se pidan.
38
 *
39
 * @author Vicente Caballero Navarro
40
 */
41
public class QuantileIntervalGenerator {
42
//        private DataSource sds;
43
        private FeatureStore featureStore;
44
        private String msFieldName;
45
        private int miNumIntervalosSolicitados;
46
        private double[] mdaValoresRuptura;
47
        private double[] mdaValInit;
48
        private int num = 0;
49

    
50
        /**
51
         * Crea un nuevo QuantileIntervalGenerator.
52
         *
53
         * @param layer DOCUMENT ME!
54
         * @param field DOCUMENT ME!
55
         * @param numIntervals DOCUMENT ME!
56
         */
57
        public QuantileIntervalGenerator(FeatureStore fs, String field,
58
                int numIntervals) {
59
                featureStore = fs;
60
                msFieldName = field;
61
                miNumIntervalosSolicitados = numIntervals;
62
        }
63

    
64
        /**
65
         * Genera los intervalos.
66
         * @throws DataException TODO
67
         *
68
         */
69
        public void generarIntervalos()
70
                throws DataException {
71
                List<Number> ordenadas = new ArrayList<Number>();
72
                List<Integer> coincidencias = new ArrayList<Integer>();
73
//                int pos = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(msFieldName);
74
                mdaValoresRuptura = new double[miNumIntervalosSolicitados - 1];
75
                mdaValInit = new double[miNumIntervalosSolicitados - 1];
76
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
77
                featureQuery.setAttributeNames(new String[]{msFieldName});
78
                FeatureSet set = null;
79
                DisposableIterator iterator = null;
80
                try {
81
                        set = featureStore.getFeatureSet(featureQuery);
82
                        iterator = set.fastIterator();
83
                        long rowCount = 0;
84
                        while (iterator.hasNext()) {
85
                                Feature feature = (Feature) iterator.next();
86
                                insertarEnVector(ordenadas, coincidencias, feature.get(0));// sds.getFieldValue(i,
87
                                                                                                                                                        // pos));
88
                                rowCount++;
89
                        }
90
                        // int MARGEN = 5;
91
                        // for (int i = 0; i < sds.getRowCount(); i++) {
92
                        // insertarEnVector(ordenadas, coincidencias, sds.getFieldValue(i,
93
                        // pos));
94
                        // }
95

    
96
                        int index = 0;
97
                        int posj = 0;
98

    
99
                        for (int i = 1; i < miNumIntervalosSolicitados; i++) {
100
                                long x = ((i * rowCount) / miNumIntervalosSolicitados);
101

    
102
                                for (int j = posj; j < ordenadas.size(); j++) {
103
                                        int auxcoin = ((Integer) coincidencias.get(j)).intValue();
104
                                        index = index + auxcoin;
105

    
106
                                        if (x <= index) {
107
                                                mdaValoresRuptura[i - 1] = getValue(ordenadas.get(j));
108

    
109
                                                /*
110
                                                 * index = (int) ((x + (auxcoin /
111
                                                 * miNumIntervalosSolicitados)) - 1);
112
                                                 */
113
                                                posj = j + 1;
114

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

    
121
                                                num++;
122

    
123
                                                break;
124
                                        }
125
                                }
126

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

    
130
                        // }
131
                } finally {
132
                        if (iterator != null) {
133
                                iterator.dispose();
134
                        }
135
                        if (set != null) {
136
                                set.dispose();
137
                        }
138
                }
139
        }
140

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

    
164
                if (rVectorDatos.size() == 0) {
165
                        rVectorDatos.add((Number) vdValorAInsertar);
166
                        coincidencia.add(new Integer(1));
167

    
168
                        return;
169
                }
170

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

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

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

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

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

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

    
200
                                return;
201
                        }
202
                }
203

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

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

    
219
                rVectorDatos.add(indice, (Number) vdValorAInsertar);
220
                coincidencia.add(indice, new Integer(1));
221
        }
222

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

    
236
        }
237

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

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

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