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 @ 42811
History | View | Annotate | Download (8.29 KB)
1 | 40560 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40560 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | 40435 | jjdelcerro | *
|
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 | 40560 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * 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 | 40560 | jjdelcerro | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 | * MA 02110-1301, USA.
|
||
20 | 40435 | jjdelcerro | *
|
21 | 40560 | jjdelcerro | * For any additional information, do not hesitate to contact us
|
22 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
23 | 40435 | jjdelcerro | */
|
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 | } |