svn-gvsig-desktop / tags / v2_0_0_Build_2011 / extensions / org.gvsig.symbology / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / impl / QuantileIntervalGenerator.java @ 33522
History | View | Annotate | Download (8.56 KB)
1 | 30010 | cordinyana | /* 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.symbology.fmap.mapcontext.rendering.legend.impl; |
||
42 | |||
43 | import java.util.ArrayList; |
||
44 | 31513 | cordinyana | import java.util.List; |
45 | 30010 | cordinyana | |
46 | import org.gvsig.fmap.dal.exception.DataException; |
||
47 | 33205 | cordinyana | import org.gvsig.tools.dispose.DisposableIterator; |
48 | 30010 | cordinyana | import org.gvsig.fmap.dal.feature.Feature; |
49 | import org.gvsig.fmap.dal.feature.FeatureQuery; |
||
50 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
51 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
52 | |||
53 | /**
|
||
54 | * Calcula los intervalos en funci?n del n?mero de intervalos que se pidan.
|
||
55 | *
|
||
56 | * @author Vicente Caballero Navarro
|
||
57 | */
|
||
58 | public class QuantileIntervalGenerator { |
||
59 | // private DataSource sds;
|
||
60 | private FeatureStore featureStore;
|
||
61 | private String msFieldName; |
||
62 | private int miNumIntervalosSolicitados; |
||
63 | private double[] mdaValoresRuptura; |
||
64 | private double[] mdaValInit; |
||
65 | private int num = 0; |
||
66 | |||
67 | /**
|
||
68 | * Crea un nuevo QuantileIntervalGenerator.
|
||
69 | *
|
||
70 | * @param layer DOCUMENT ME!
|
||
71 | * @param field DOCUMENT ME!
|
||
72 | * @param numIntervals DOCUMENT ME!
|
||
73 | */
|
||
74 | public QuantileIntervalGenerator(FeatureStore fs, String field, |
||
75 | int numIntervals) {
|
||
76 | featureStore = fs; |
||
77 | msFieldName = field; |
||
78 | miNumIntervalosSolicitados = numIntervals; |
||
79 | } |
||
80 | |||
81 | /**
|
||
82 | * Genera los intervalos.
|
||
83 | * @throws DataException TODO
|
||
84 | *
|
||
85 | */
|
||
86 | public void generarIntervalos() |
||
87 | throws DataException {
|
||
88 | 31513 | cordinyana | List<Number> ordenadas = new ArrayList<Number>(); |
89 | List<Integer> coincidencias = new ArrayList<Integer>(); |
||
90 | 30010 | cordinyana | // int pos = ((FeatureType)featureStore.getFeatureTypes().get(0)).getIndex(msFieldName);
|
91 | mdaValoresRuptura = new double[miNumIntervalosSolicitados - 1]; |
||
92 | mdaValInit = new double[miNumIntervalosSolicitados - 1]; |
||
93 | FeatureQuery featureQuery=featureStore.createFeatureQuery(); |
||
94 | featureQuery.setAttributeNames(new String[]{msFieldName}); |
||
95 | FeatureSet set = null;
|
||
96 | DisposableIterator iterator = null;
|
||
97 | try {
|
||
98 | set = featureStore.getFeatureSet(featureQuery); |
||
99 | iterator = set.fastIterator(); |
||
100 | long rowCount = 0; |
||
101 | while (iterator.hasNext()) {
|
||
102 | Feature feature = (Feature) iterator.next(); |
||
103 | insertarEnVector(ordenadas, coincidencias, feature.get(0));// sds.getFieldValue(i, |
||
104 | // pos));
|
||
105 | rowCount++; |
||
106 | } |
||
107 | // int MARGEN = 5;
|
||
108 | // for (int i = 0; i < sds.getRowCount(); i++) {
|
||
109 | // insertarEnVector(ordenadas, coincidencias, sds.getFieldValue(i,
|
||
110 | // pos));
|
||
111 | // }
|
||
112 | |||
113 | int index = 0; |
||
114 | int posj = 0; |
||
115 | |||
116 | for (int i = 1; i < miNumIntervalosSolicitados; i++) { |
||
117 | long x = ((i * rowCount) / miNumIntervalosSolicitados);
|
||
118 | |||
119 | for (int j = posj; j < ordenadas.size(); j++) { |
||
120 | int auxcoin = ((Integer) coincidencias.get(j)).intValue(); |
||
121 | index = index + auxcoin; |
||
122 | |||
123 | if (x <= index) {
|
||
124 | mdaValoresRuptura[i - 1] = getValue(ordenadas.get(j));
|
||
125 | |||
126 | /*
|
||
127 | * index = (int) ((x + (auxcoin /
|
||
128 | * miNumIntervalosSolicitados)) - 1);
|
||
129 | */
|
||
130 | posj = j + 1;
|
||
131 | |||
132 | if (posj < ordenadas.size()) {
|
||
133 | mdaValInit[i - 1] = getValue(ordenadas.get(posj));
|
||
134 | } else {
|
||
135 | mdaValInit[i - 1] = getValue(ordenadas.get(j));
|
||
136 | } |
||
137 | |||
138 | num++; |
||
139 | |||
140 | break;
|
||
141 | } |
||
142 | } |
||
143 | |||
144 | // double value=getValue(sds.getFieldValue(x,pos));
|
||
145 | } |
||
146 | |||
147 | // }
|
||
148 | } finally {
|
||
149 | if (iterator != null) { |
||
150 | iterator.dispose(); |
||
151 | } |
||
152 | if (set != null) { |
||
153 | set.dispose(); |
||
154 | } |
||
155 | } |
||
156 | } |
||
157 | |||
158 | /**
|
||
159 | * Esta funci?n busca en el vector de datos la posici?n que le corresponde
|
||
160 | * al valor almacenado en vdValor y devuelve dicha posici?n en
|
||
161 | * vdValorAInsertar. Para hallar la posici?n se realiza una b?squeda
|
||
162 | * binaria. Si se trata de un elemento que ya est? en el vector devolvemos
|
||
163 | * el ?ndice que le corresponde en rlIndiceCorrespondiente y false en
|
||
164 | * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
|
||
165 | * insertar... devolvemos el ?ndice en el que ir?a y True en
|
||
166 | * rbNuevoElemento En caso de que ocurra alg?n error devuelve false
|
||
167 | *
|
||
168 | * @param rVectorDatos ArrayList con los datos.
|
||
169 | * @param coincidencia ?ndice.
|
||
170 | * @param vdValorAInsertar Valor a insertar.
|
||
171 | */
|
||
172 | 31513 | cordinyana | private void insertarEnVector(List<Number> rVectorDatos, |
173 | List<Integer> coincidencia, Object vdValorAInsertar) { |
||
174 | 30010 | cordinyana | int llIndiceIzq;
|
175 | int llIndiceDer;
|
||
176 | int llMedio;
|
||
177 | int indice = -1; |
||
178 | double ldValorComparacion;
|
||
179 | double valorAInsertar = getValue(vdValorAInsertar);
|
||
180 | |||
181 | if (rVectorDatos.size() == 0) { |
||
182 | 31513 | cordinyana | rVectorDatos.add((Number) vdValorAInsertar);
|
183 | 30010 | cordinyana | coincidencia.add(new Integer(1)); |
184 | |||
185 | return;
|
||
186 | } |
||
187 | |||
188 | llIndiceIzq = 0;
|
||
189 | llIndiceDer = rVectorDatos.size() - 1;
|
||
190 | llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi?n entera! |
||
191 | |||
192 | while (llIndiceIzq <= llIndiceDer) {
|
||
193 | //'Coger el valor situado en la mitad de la zona de b?squeda como valor de comparaci?n
|
||
194 | ldValorComparacion = getValue( rVectorDatos.get(llMedio)); |
||
195 | |||
196 | //'Si el valor a insertar es mayor que el valor de comparaci?n...
|
||
197 | if (valorAInsertar > ldValorComparacion) {
|
||
198 | // 'La zona de b?squeda queda restringida a la parte de la derecha
|
||
199 | llIndiceIzq = llMedio + 1;
|
||
200 | llMedio = (llIndiceIzq + llIndiceDer) / 2;
|
||
201 | |||
202 | // 'Si el valor a insertar es menor que el valor de comparaci?n...
|
||
203 | } else if (valorAInsertar < ldValorComparacion) { |
||
204 | // 'La zona de b?squeda queda restringida a la parte de la derecha
|
||
205 | llIndiceDer = llMedio - 1;
|
||
206 | llMedio = (llIndiceIzq + llIndiceDer) / 2;
|
||
207 | |||
208 | // 'Si el valor de comparaci?n coincide con el valor a insertar
|
||
209 | } else if (valorAInsertar == ldValorComparacion) { |
||
210 | indice = llMedio; |
||
211 | |||
212 | int index = rVectorDatos.indexOf(vdValorAInsertar);
|
||
213 | int coin = ((Integer) coincidencia.get(index)).intValue() + 1; |
||
214 | coincidencia.remove(index); |
||
215 | coincidencia.add(index, new Integer(coin)); |
||
216 | |||
217 | return;
|
||
218 | } |
||
219 | } |
||
220 | |||
221 | // 'Nota:
|
||
222 | // 'En este caso (cuando en rbNuevoElemento se devuelve True) lo que hay que hacer al salir de esta funci?n
|
||
223 | // 'es a?adir un nuevo elemento al vector y desplazar todos los valores correspondientes a partir de rlIndiceCorrespondiente
|
||
224 | // '?D?nde va el nuevo elemento?
|
||
225 | // 'El ?ltimo sitio estudiado viene dado por el valor de llMedio.
|
||
226 | // 'Si el valor a insertar es menor que el valor almacenado en la posici?n llMedio, el nuevo valor deber? ir a su izquierda.
|
||
227 | // 'Si fuera mayor deber?a ir a su derecha.
|
||
228 | ldValorComparacion = getValue( rVectorDatos.get(llMedio)); |
||
229 | |||
230 | if (valorAInsertar > ldValorComparacion) {
|
||
231 | indice = llMedio + 1;
|
||
232 | } else {
|
||
233 | indice = llMedio; |
||
234 | } |
||
235 | |||
236 | 31513 | cordinyana | rVectorDatos.add(indice, (Number) vdValorAInsertar);
|
237 | 30010 | cordinyana | coincidencia.add(indice, new Integer(1)); |
238 | } |
||
239 | |||
240 | /**
|
||
241 | * Devuelve el valor en un double del Value que se pasa como par?metro.
|
||
242 | *
|
||
243 | * @param value Value.
|
||
244 | *
|
||
245 | * @return valor.
|
||
246 | */
|
||
247 | private double getValue(Object value) { |
||
248 | if (value instanceof Number) { |
||
249 | return ((Number) value).doubleValue(); |
||
250 | } |
||
251 | return 0; |
||
252 | |||
253 | } |
||
254 | |||
255 | /**
|
||
256 | * Devuelve el valor del punto de ruptura seg?n el ?ndice que se pasa como
|
||
257 | * par?metro.
|
||
258 | *
|
||
259 | * @param index ?ndice del punto de ruptura.
|
||
260 | *
|
||
261 | * @return valor.
|
||
262 | */
|
||
263 | public double getValRuptura(int index) { |
||
264 | return mdaValoresRuptura[index];
|
||
265 | } |
||
266 | |||
267 | /**
|
||
268 | * Devuelve el valor inicial de cada intervalo.
|
||
269 | *
|
||
270 | * @param index ?ndice del intervalo.
|
||
271 | *
|
||
272 | * @return valor del intervalo.
|
||
273 | */
|
||
274 | public double getValInit(int index) { |
||
275 | return mdaValInit[index];
|
||
276 | } |
||
277 | |||
278 | /**
|
||
279 | * Devuelve el n?mero de intervalos que se han generado.
|
||
280 | *
|
||
281 | * @return N?mero de intervalos generados.
|
||
282 | */
|
||
283 | public int getNumIntervalGen() { |
||
284 | return num + 1; |
||
285 | } |
||
286 | } |