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 | 2076 | vcaballero | /* 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 | } |