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 / NaturalIntervalGenerator.java @ 40560
History | View | Annotate | Download (30.3 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.slf4j.Logger; |
||
30 | import org.slf4j.LoggerFactory; |
||
31 | |||
32 | import org.gvsig.fmap.dal.exception.DataException; |
||
33 | import org.gvsig.tools.dispose.DisposableIterator; |
||
34 | import org.gvsig.fmap.dal.feature.Feature; |
||
35 | import org.gvsig.fmap.dal.feature.FeatureQuery; |
||
36 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
37 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
38 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
39 | |||
40 | /**
|
||
41 | * Calcula los intervalos naturales.
|
||
42 | *
|
||
43 | * @author Vicente Caballero Navarro
|
||
44 | */
|
||
45 | public class NaturalIntervalGenerator { |
||
46 | |||
47 | private static final Logger logger = |
||
48 | LoggerFactory.getLogger(NaturalIntervalGenerator.class); |
||
49 | |||
50 | private String msFieldName; |
||
51 | private int miNumIntervalosSolicitados; |
||
52 | private int miNumIntervalosGenerados; |
||
53 | private double[] mdaValoresRuptura; |
||
54 | private double[] mdaValInit; |
||
55 | private FeatureStore featureStore;
|
||
56 | |||
57 | /**
|
||
58 | * Crea un nuevo IntervalGenerator.
|
||
59 | *
|
||
60 | * @param layer AlphanumericData
|
||
61 | * @param field Nombre del campo.
|
||
62 | * @param numIntervals N�mero de intervalos.
|
||
63 | */
|
||
64 | public NaturalIntervalGenerator(FeatureStore fs, String field, |
||
65 | int numIntervals) {
|
||
66 | featureStore = fs; |
||
67 | msFieldName = field; |
||
68 | miNumIntervalosSolicitados = numIntervals; |
||
69 | } |
||
70 | |||
71 | /**
|
||
72 | * Esta funci�n busca en el vector de datos la posici�n que le corresponde
|
||
73 | * al valor almacenado en vdValor y devuelve dicha posici�n en
|
||
74 | * vdValorAInsertar. Para hallar la posici�n se realiza una b�squeda
|
||
75 | * binaria. Si se trata de un elemento que ya est� en el vector devolvemos
|
||
76 | * el �ndice que le corresponde en rlIndiceCorrespondiente y false en
|
||
77 | * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
|
||
78 | * insertar... devolvemos el �ndice en el que ir�a y True en
|
||
79 | * rbNuevoElemento En caso de que ocurra alg�n error devuelve false
|
||
80 | *
|
||
81 | * @param rVectorDatos ArrayList con los datos.
|
||
82 | * @param vdValorAInsertar Valor a insertar.
|
||
83 | * @param rlIndiceCorrespondiente �ndice.
|
||
84 | * @param rbNuevoElemento True si es un nuevo elemento.
|
||
85 | *
|
||
86 | * @return True si ha conseguido correctamente la posici�n en el vector.
|
||
87 | */
|
||
88 | private boolean mbObtenerPosicionEnVector( |
||
89 | List<udtDatosEstudio> rVectorDatos,
|
||
90 | double vdValorAInsertar, int[] rlIndiceCorrespondiente, |
||
91 | boolean[] rbNuevoElemento) { |
||
92 | int llIndiceIzq;
|
||
93 | int llIndiceDer;
|
||
94 | int llMedio;
|
||
95 | |||
96 | double ldValorComparacion;
|
||
97 | |||
98 | rbNuevoElemento[0] = false; |
||
99 | rlIndiceCorrespondiente[0] = -1; |
||
100 | |||
101 | //'Si el vector estiviese vac�o... (tuviese un s�lo elemento y el n�mero de coincidencias fuese 0)
|
||
102 | if (rVectorDatos.size() == 1) { |
||
103 | if (((udtDatosEstudio) rVectorDatos.get(0)).Coincidencias == 0) { |
||
104 | rlIndiceCorrespondiente[0] = 0; |
||
105 | rbNuevoElemento[0] = false; //'No tenemos que a�adir un nuevo elemento al vector |
||
106 | |||
107 | return true; |
||
108 | } |
||
109 | } |
||
110 | |||
111 | llIndiceIzq = 0;
|
||
112 | llIndiceDer = rVectorDatos.size() - 1;
|
||
113 | llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi�n entera! |
||
114 | |||
115 | while (llIndiceIzq <= llIndiceDer) {
|
||
116 | //'Coger el valor situado en la mitad de la zona de b�squeda como valor de comparaci�n
|
||
117 | ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor; |
||
118 | |||
119 | //'Si el valor a insertar es mayor que el valor de comparaci�n...
|
||
120 | if (vdValorAInsertar > ldValorComparacion) {
|
||
121 | // 'La zona de b�squeda queda restringida a la parte de la derecha
|
||
122 | llIndiceIzq = llMedio + 1;
|
||
123 | llMedio = (llIndiceIzq + llIndiceDer) / 2;
|
||
124 | |||
125 | // 'Si el valor a insertar es menor que el valor de comparaci�n...
|
||
126 | } else if (vdValorAInsertar < ldValorComparacion) { |
||
127 | // 'La zona de b�squeda queda restringida a la parte de la derecha
|
||
128 | llIndiceDer = llMedio - 1;
|
||
129 | llMedio = (llIndiceIzq + llIndiceDer) / 2;
|
||
130 | |||
131 | // 'Si el valor de comparaci�n coincide con el valor a insertar
|
||
132 | } else if (vdValorAInsertar == ldValorComparacion) { |
||
133 | rlIndiceCorrespondiente[0] = llMedio;
|
||
134 | rbNuevoElemento[0] = false; |
||
135 | |||
136 | return true; |
||
137 | } |
||
138 | } |
||
139 | |||
140 | // 'Si llegamos a este punto es que no hemos encontrado el valor a insertar en el vector, es decir,
|
||
141 | // 'seguro que tendremos que a�adir un nuevo elemento.
|
||
142 | rbNuevoElemento[0] = true; |
||
143 | |||
144 | // 'Nota:
|
||
145 | // 'En este caso (cuando en rbNuevoElemento se devuelve True) lo que hay que hacer al salir de esta funci�n
|
||
146 | // 'es a�adir un nuevo elemento al vector y desplazar todos los valores correspondientes a partir de rlIndiceCorrespondiente
|
||
147 | // '�D�nde va el nuevo elemento?
|
||
148 | // 'El �ltimo sitio estudiado viene dado por el valor de llMedio.
|
||
149 | // 'Si el valor a insertar es menor que el valor almacenado en la posici�n llMedio, el nuevo valor deber� ir a su izquierda.
|
||
150 | // 'Si fuera mayor deber�a ir a su derecha.
|
||
151 | ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor; |
||
152 | |||
153 | if (vdValorAInsertar > ldValorComparacion) {
|
||
154 | rlIndiceCorrespondiente[0] = llMedio + 1; |
||
155 | } else {
|
||
156 | rlIndiceCorrespondiente[0] = llMedio;
|
||
157 | } |
||
158 | |||
159 | return true; |
||
160 | } |
||
161 | |||
162 | /**
|
||
163 | * M�todo para generar los intervalos.
|
||
164 | *
|
||
165 | * @return true si se han generado correctamente.
|
||
166 | * @throws DataException TODO
|
||
167 | */
|
||
168 | public boolean generarIntervalos() |
||
169 | throws DataException {
|
||
170 | List<udtDatosEstudio> lVectorDatos;
|
||
171 | double[] ldMediaTotal = new double[1]; |
||
172 | double[] ldSDAM = new double[1]; |
||
173 | |||
174 | int[] llaIndicesRupturas; |
||
175 | |||
176 | double[] ldUltimaGVF = new double[1]; |
||
177 | double[] ldNuevaGVF = new double[1]; |
||
178 | |||
179 | int i;
|
||
180 | int liNumClasesReales;
|
||
181 | int llNumElementosPorClase;
|
||
182 | |||
183 | // 'Obtener los datos a estudiar ordenados ascendentemente y obtener la media total
|
||
184 | //ReDim lVectorDatos(0)
|
||
185 | lVectorDatos = new ArrayList<udtDatosEstudio>(); |
||
186 | |||
187 | lVectorDatos.add(new udtDatosEstudio());
|
||
188 | |||
189 | if (!mbObtenerDatos(lVectorDatos, ldMediaTotal)) {
|
||
190 | return false; //SalidaSinMensaje |
||
191 | } |
||
192 | |||
193 | logger.info("Analizando datos en generarIntervalos() ...");
|
||
194 | |||
195 | /// Call gEstablecerDescripcionProceso("Analizando datos ...", False)
|
||
196 | // 'Calcular la suma de las desviaciones t�picas del total de los datos respecto de la media total
|
||
197 | ldSDAM[0] = mbGetSumSquaredDeviationArrayMean(lVectorDatos,
|
||
198 | ldMediaTotal[0]);
|
||
199 | |||
200 | ///if (lVectorDatos.length==0){
|
||
201 | if (lVectorDatos.isEmpty()) {
|
||
202 | // 'S�lo se pueden generar dos intervalos -> hay un valor de ruptura
|
||
203 | ///ReDim mdaValoresRuptura(0)
|
||
204 | mdaValoresRuptura[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor; |
||
205 | mdaValInit[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor; |
||
206 | miNumIntervalosGenerados = 2;
|
||
207 | |||
208 | return true; |
||
209 | } |
||
210 | |||
211 | // 'Calculamos el n�mero m�ximo de clases reales que podemos generar.
|
||
212 | // 'Este n�mero ser�a igual al n� de elementos que tenga el vector de datos.
|
||
213 | if (miNumIntervalosSolicitados > (lVectorDatos.size())) {
|
||
214 | liNumClasesReales = lVectorDatos.size() + 1;
|
||
215 | } else {
|
||
216 | liNumClasesReales = miNumIntervalosSolicitados; |
||
217 | } |
||
218 | |||
219 | // 'Establecemos las clases iniciales especificando unos �ndices de ruptura en ppo. equidistantes
|
||
220 | llaIndicesRupturas = new int[liNumClasesReales - 1]; |
||
221 | llNumElementosPorClase = (lVectorDatos.size()) / liNumClasesReales; |
||
222 | |||
223 | for (i = 0; i < llaIndicesRupturas.length; i++) { |
||
224 | if (i == 0) { |
||
225 | llaIndicesRupturas[i] = llNumElementosPorClase - 1;
|
||
226 | } else {
|
||
227 | llaIndicesRupturas[i] = llaIndicesRupturas[i - 1] +
|
||
228 | llNumElementosPorClase; |
||
229 | } |
||
230 | } |
||
231 | |||
232 | udtDatosClase[] ldaSDCM_Parciales = new udtDatosClase[llaIndicesRupturas.length + |
||
233 | 1];
|
||
234 | udtDatosClase[] ldaSDCM_Validos = new udtDatosClase[llaIndicesRupturas.length + |
||
235 | 1];
|
||
236 | |||
237 | ///ReDim ldaSDCM_Parciales(UBound(llaIndicesRupturas()) + 1)
|
||
238 | ///ReDim ldaSDCM_Validos(UBound(ldaSDCM_Parciales()) + 1)
|
||
239 | if (llaIndicesRupturas.length == 0) { |
||
240 | return true; |
||
241 | } |
||
242 | |||
243 | // 'Calcular la bondad inicial
|
||
244 | if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales, llaIndicesRupturas,
|
||
245 | ldSDAM[0], ldUltimaGVF, -1, false)) { |
||
246 | // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"el_numero_maximo_de_intervalos_para_este_campo_es")+": "+lVectorDatos.size());
|
||
247 | miNumIntervalosSolicitados=lVectorDatos.size(); |
||
248 | generarIntervalos(); |
||
249 | return false; |
||
250 | } |
||
251 | |||
252 | ldaSDCM_Validos = getArray(ldaSDCM_Parciales); |
||
253 | |||
254 | boolean lbMoverADerecha;
|
||
255 | boolean lbMoverAIzquierda;
|
||
256 | boolean lbIntentarDesplazamiento;
|
||
257 | int llIndiceRupturaOriginal;
|
||
258 | |||
259 | long k;
|
||
260 | double ldGVFentrepasadas;
|
||
261 | |||
262 | ldGVFentrepasadas = ldUltimaGVF[0];
|
||
263 | |||
264 | //'liNumClasesReales no ser� muy grande (11 es el m�ximo)
|
||
265 | for (k = 1; k <= 100; k++) { |
||
266 | // 'Para cada �ndice de ruptura...
|
||
267 | for (i = 0; i < (llaIndicesRupturas.length); i++) { |
||
268 | lbMoverADerecha = false;
|
||
269 | lbMoverAIzquierda = false;
|
||
270 | llIndiceRupturaOriginal = llaIndicesRupturas[i]; |
||
271 | ldaSDCM_Validos = getArray(ldaSDCM_Parciales); |
||
272 | |||
273 | //'Hay que decidir hacia donde hay que desplazar el �ndice de ruptura
|
||
274 | //'Probamos moviendo a derecha (si se puede)
|
||
275 | lbIntentarDesplazamiento = false;
|
||
276 | |||
277 | if (i == (llaIndicesRupturas.length - 1)) { |
||
278 | if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) { |
||
279 | lbIntentarDesplazamiento = true;
|
||
280 | } |
||
281 | } else {
|
||
282 | if ((llaIndicesRupturas[i] + 1) < llaIndicesRupturas[i + 1]) { |
||
283 | lbIntentarDesplazamiento = true;
|
||
284 | } //'If (llaIndicesRupturas(i) + 1) < llaIndicesRupturas(i + 1) Then
|
||
285 | } //'If i = UBound(llaIndicesRupturas) Then
|
||
286 | |||
287 | if (lbIntentarDesplazamiento) {
|
||
288 | llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
|
||
289 | |||
290 | if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
|
||
291 | llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
|
||
292 | false)) {
|
||
293 | return false; |
||
294 | } |
||
295 | |||
296 | if (ldNuevaGVF[0] > ldUltimaGVF[0]) { |
||
297 | lbMoverADerecha = true;
|
||
298 | ldaSDCM_Validos = getArray(ldaSDCM_Parciales); |
||
299 | } else {
|
||
300 | //'Dejamos el �ndice de ruputura como estaba y probamos con un desplazamiento a izquierda
|
||
301 | llaIndicesRupturas[i] = llIndiceRupturaOriginal; |
||
302 | ldaSDCM_Parciales = getArray(ldaSDCM_Validos); |
||
303 | } |
||
304 | } //'If lbIntentarDesplazamiento Then
|
||
305 | |||
306 | lbIntentarDesplazamiento = false;
|
||
307 | |||
308 | //'Probamos moviendo a izquierda (si se puede y no estamos moviendo ya a derechas)
|
||
309 | if (!lbMoverADerecha) {
|
||
310 | if (i == 0) { //LBound(llaIndicesRupturas) Then |
||
311 | |||
312 | if ((llaIndicesRupturas[i] - 1) >= 0) { //LBound(lVectorDatos()) Then |
||
313 | lbIntentarDesplazamiento = true;
|
||
314 | } //'If (llaIndicesRupturas(i) - 1) >= LBound(lVectorDatos()) Then
|
||
315 | } else {
|
||
316 | if ((llaIndicesRupturas[i] - 1) > llaIndicesRupturas[i - |
||
317 | 1]) {
|
||
318 | lbIntentarDesplazamiento = true;
|
||
319 | } //'If (llaIndicesRupturas(i) - 1) > llaIndicesRupturas(i - 1) Then
|
||
320 | } //'If i = LBound(llaIndicesRupturas) Then
|
||
321 | } //'If Not lbMoverADerecha Then
|
||
322 | |||
323 | if (lbIntentarDesplazamiento) {
|
||
324 | llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1;
|
||
325 | |||
326 | if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
|
||
327 | llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
|
||
328 | true)) {
|
||
329 | return false; |
||
330 | } |
||
331 | |||
332 | if (ldNuevaGVF[0] > ldUltimaGVF[0]) { |
||
333 | lbMoverAIzquierda = true;
|
||
334 | ldaSDCM_Validos = getArray(ldaSDCM_Parciales); |
||
335 | } else {
|
||
336 | //'Dejamos el �ndice de ruputura como estaba
|
||
337 | llaIndicesRupturas[i] = llIndiceRupturaOriginal; |
||
338 | ldaSDCM_Parciales = getArray(ldaSDCM_Validos); |
||
339 | } |
||
340 | } //'If lbIntentarDesplazamiento Then
|
||
341 | |||
342 | lbIntentarDesplazamiento = false;
|
||
343 | |||
344 | //'Si se ha decidido desplazar el �ndice ... continuamos hasta que no podamos mejorar la GVF
|
||
345 | if (lbMoverAIzquierda || lbMoverADerecha) {
|
||
346 | ldUltimaGVF[0] = ldNuevaGVF[0]; |
||
347 | |||
348 | boolean exit = false; |
||
349 | |||
350 | while (!exit) {
|
||
351 | llIndiceRupturaOriginal = llaIndicesRupturas[i]; |
||
352 | |||
353 | if (lbMoverADerecha) {
|
||
354 | if (i == (llaIndicesRupturas.length - 1)) { |
||
355 | if ((llaIndicesRupturas[i] + 1) >= lVectorDatos.size()) { |
||
356 | exit = true;
|
||
357 | } |
||
358 | } else {
|
||
359 | if ((llaIndicesRupturas[i] + 1) >= llaIndicesRupturas[i + |
||
360 | 1]) {
|
||
361 | exit = true;
|
||
362 | } |
||
363 | } //'If i = UBound(llaIndicesRupturas) Then
|
||
364 | |||
365 | llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
|
||
366 | } else { //'If lbMoverAIzquierda Then |
||
367 | |||
368 | if (i == 0) { //LBound(llaIndicesRupturas) Then |
||
369 | |||
370 | if ((llaIndicesRupturas[i] - 1) < 0) { //LBound(lVectorDatos()) Then Exit Do |
||
371 | exit = true;
|
||
372 | } |
||
373 | } else {
|
||
374 | if ((llaIndicesRupturas[i] - 1) <= llaIndicesRupturas[i - |
||
375 | 1]) {
|
||
376 | exit = true;
|
||
377 | } |
||
378 | } //'If i = LBound(llaIndicesRupturas) Then
|
||
379 | |||
380 | llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1; ////////////////// |
||
381 | } //'If lbMoverADerecha Then
|
||
382 | |||
383 | if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
|
||
384 | llaIndicesRupturas, ldSDAM[0], ldNuevaGVF,
|
||
385 | i, lbMoverAIzquierda)) { |
||
386 | return false; |
||
387 | } |
||
388 | |||
389 | if (ldNuevaGVF[0] < ldUltimaGVF[0]) { |
||
390 | // 'Dejar el �ndice donde estaba
|
||
391 | llaIndicesRupturas[i] = llIndiceRupturaOriginal; |
||
392 | ldaSDCM_Parciales = getArray(ldaSDCM_Validos); |
||
393 | exit = true;
|
||
394 | } else {
|
||
395 | ldUltimaGVF[0] = ldNuevaGVF[0]; |
||
396 | ldaSDCM_Validos = getArray(ldaSDCM_Parciales); |
||
397 | } |
||
398 | } |
||
399 | } //'If lbMoverAIzquierda Or lbMoverADerecha Then
|
||
400 | } |
||
401 | |||
402 | if (ldUltimaGVF[0] <= ldGVFentrepasadas) { |
||
403 | i = 101;
|
||
404 | } |
||
405 | |||
406 | ldGVFentrepasadas = ldUltimaGVF[0];
|
||
407 | } |
||
408 | |||
409 | // 'A partir de aqu� ya no se puede cancelar nada
|
||
410 | mdaValoresRuptura = new double[llaIndicesRupturas.length]; |
||
411 | mdaValInit = new double[llaIndicesRupturas.length]; |
||
412 | |||
413 | for (i = 0; i < mdaValoresRuptura.length; i++) { // LBound(mdaValoresRuptura) To UBound(mdaValoresRuptura) |
||
414 | if (llaIndicesRupturas[i]==-1) { |
||
415 | llaIndicesRupturas[i]=1;
|
||
416 | } |
||
417 | if (llaIndicesRupturas[i]>lVectorDatos.size()-1) { |
||
418 | llaIndicesRupturas[i]=lVectorDatos.size()-1;
|
||
419 | } |
||
420 | mdaValoresRuptura[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor; |
||
421 | |||
422 | if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) { |
||
423 | mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i] + |
||
424 | 1)).Valor;
|
||
425 | } else {
|
||
426 | mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor; |
||
427 | } |
||
428 | |||
429 | // 'Hay que aplicar una peque�a correcci�n a los valores de ruptura para que los intervalos que genera
|
||
430 | // 'mapobjects se aprechen en su totalidad, o lo que es lo mismo, vengan todos representados en el mapa.
|
||
431 | // 'Con esto tambi�n se consigue hallar intervalos equivalentes a los de ArcView. Esta correcci�n consiste
|
||
432 | //'en sumar el m�nimo incremento a los valores de ruptura. No lo hago aqu� sino en la ventana de propiedades de capa.
|
||
433 | } |
||
434 | |||
435 | miNumIntervalosGenerados = mdaValoresRuptura.length + 2;
|
||
436 | |||
437 | ldaSDCM_Validos = null;
|
||
438 | ldaSDCM_Parciales = null;
|
||
439 | lVectorDatos = null;
|
||
440 | |||
441 | return true; |
||
442 | } |
||
443 | |||
444 | /**
|
||
445 | * DOCUMENT ME!
|
||
446 | *
|
||
447 | * @param array DOCUMENT ME!
|
||
448 | *
|
||
449 | * @return DOCUMENT ME!
|
||
450 | */
|
||
451 | private udtDatosClase[] getArray(udtDatosClase[] array) { |
||
452 | udtDatosClase[] aux = new udtDatosClase[array.length]; |
||
453 | |||
454 | for (int i = 0; i < array.length; i++) { |
||
455 | aux[i] = new udtDatosClase();
|
||
456 | aux[i].Media = array[i].Media; |
||
457 | aux[i].NumElementos = array[i].NumElementos; |
||
458 | aux[i].SDCM = array[i].SDCM; |
||
459 | aux[i].SumaCuadradoTotal = array[i].SumaCuadradoTotal; |
||
460 | aux[i].SumaTotal = array[i].SumaTotal; |
||
461 | } |
||
462 | |||
463 | return aux;
|
||
464 | } |
||
465 | |||
466 | /**
|
||
467 | * Devuelve la "SDAM" de un conjunto de datos que vienen almacenados en el
|
||
468 | * vector rVectorDatos
|
||
469 | *
|
||
470 | * @param rVectorDatos Datos
|
||
471 | * @param vdMedia Media
|
||
472 | *
|
||
473 | * @return suma de las desviaciones t�picas del total de los datos respecto
|
||
474 | * de la media total
|
||
475 | */
|
||
476 | private double mbGetSumSquaredDeviationArrayMean( |
||
477 | List<udtDatosEstudio> rVectorDatos,
|
||
478 | double vdMedia) {
|
||
479 | int i;
|
||
480 | |||
481 | double rdSDAM = 0; |
||
482 | |||
483 | for (i = 0; i < rVectorDatos.size(); i++) { // LBound(rVectorDatos) To UBound(rVectorDatos) |
||
484 | rdSDAM = rdSDAM + |
||
485 | (Math.pow((((udtDatosEstudio) rVectorDatos.get(i)).Valor -
|
||
486 | vdMedia), 2) * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
|
||
487 | } |
||
488 | |||
489 | return rdSDAM;
|
||
490 | } |
||
491 | |||
492 | /**
|
||
493 | * Esta funci�n obtiene los datos en los que queremos hallar las rupturas
|
||
494 | * naturales. Los datos se devuelven ordenados en un vector. Tambi�n
|
||
495 | * devuelve la media total
|
||
496 | *
|
||
497 | * @param rVectorDatos Datos
|
||
498 | * @param rdMediaTotal Media total
|
||
499 | *
|
||
500 | * @return True si se ha calculado correctamente.
|
||
501 | * @throws DataException TODO
|
||
502 | */
|
||
503 | private boolean mbObtenerDatos(List<udtDatosEstudio> rVectorDatos, |
||
504 | double[] rdMediaTotal) |
||
505 | throws DataException {
|
||
506 | double ldValor;
|
||
507 | |||
508 | // int i;
|
||
509 | long llRecordCount=0; |
||
510 | |||
511 | int[] llIndice = new int[1]; |
||
512 | boolean[] lbNuevoElemento = new boolean[1]; |
||
513 | //int j;
|
||
514 | |||
515 | // llRecordCount = ds.getRowCount();
|
||
516 | |||
517 | if (!gbExisteCampoEnRegistro(featureStore, msFieldName)) {
|
||
518 | if (msFieldName == "") { |
||
519 | System.out.println(
|
||
520 | "No se ha establecido el nombre del campo origen!");
|
||
521 | } else {
|
||
522 | System.out.println("El campo '" + msFieldName + |
||
523 | "' no pertence a la capa!");
|
||
524 | } |
||
525 | |||
526 | return false; |
||
527 | } |
||
528 | FeatureQuery featureQuery=featureStore.createFeatureQuery(); |
||
529 | featureQuery.setAttributeNames(new String[]{msFieldName}); |
||
530 | FeatureSet set = null;
|
||
531 | DisposableIterator iterator = null;
|
||
532 | try {
|
||
533 | set = featureStore.getFeatureSet(featureQuery); |
||
534 | iterator = set.fastIterator(); |
||
535 | while (iterator.hasNext()) {
|
||
536 | Feature feature = (Feature) iterator.next(); |
||
537 | |||
538 | // 'Nos cuidamos de recorrer todos los registros sin consultar
|
||
539 | // la propiedad EOF del recordset
|
||
540 | // for (i = 0; i < llRecordCount; i++) {
|
||
541 | try {
|
||
542 | ldValor = feature.getDouble(0);
|
||
543 | llRecordCount++; |
||
544 | } catch (Exception e) { |
||
545 | // llRecordCount--;
|
||
546 | continue;
|
||
547 | } |
||
548 | rdMediaTotal[0] = rdMediaTotal[0] + ldValor; |
||
549 | |||
550 | // 'Hay que insertar el valor en la posici�n adecuada. Para
|
||
551 | // ello hacemos una b�squeda binaria
|
||
552 | if (!mbObtenerPosicionEnVector(rVectorDatos, ldValor, llIndice,
|
||
553 | lbNuevoElemento)) { |
||
554 | return false; |
||
555 | } |
||
556 | |||
557 | if (!lbNuevoElemento[0]) { |
||
558 | if ((llIndice[0] < 0) |
||
559 | || (llIndice[0] > rVectorDatos.size())) {
|
||
560 | System.out.println("�ndice incorrecto!"); |
||
561 | |||
562 | return false; |
||
563 | } |
||
564 | |||
565 | ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Valor = ldValor; // 'Por |
||
566 | // si
|
||
567 | // fuese
|
||
568 | // el
|
||
569 | // primer
|
||
570 | // elemento
|
||
571 | |||
572 | // 'Incrementamos el n� de coincidencias y damos el valor
|
||
573 | // por insertado
|
||
574 | ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias = ((udtDatosEstudio) rVectorDatos
|
||
575 | .get(llIndice[0])).Coincidencias +
|
||
576 | 1;
|
||
577 | } else {
|
||
578 | udtDatosEstudio udt = new udtDatosEstudio();
|
||
579 | udt.Valor = ldValor; |
||
580 | udt.Coincidencias = 1;
|
||
581 | rVectorDatos.add(llIndice[0], udt);
|
||
582 | } |
||
583 | } |
||
584 | |||
585 | rdMediaTotal[0] = rdMediaTotal[0] / llRecordCount; |
||
586 | |||
587 | return true; |
||
588 | } finally {
|
||
589 | if (iterator != null) { |
||
590 | iterator.dispose(); |
||
591 | } |
||
592 | if (set != null) { |
||
593 | set.dispose(); |
||
594 | } |
||
595 | } |
||
596 | } |
||
597 | |||
598 | /**
|
||
599 | * Devuelve true si existe el campo en el registro.
|
||
600 | *
|
||
601 | * @param recordset Recordset.
|
||
602 | * @param msFieldName2 Nombre del campo.
|
||
603 | *
|
||
604 | * @return True si existe el campo.
|
||
605 | * @throws DataException TODO
|
||
606 | *
|
||
607 | */
|
||
608 | private boolean gbExisteCampoEnRegistro(FeatureStore fs, |
||
609 | String msFieldName2) throws DataException { |
||
610 | if (((FeatureType)fs.getFeatureTypes().get(0)).getIndex(msFieldName2) == -1) { |
||
611 | return false; |
||
612 | } |
||
613 | |||
614 | return true; |
||
615 | } |
||
616 | |||
617 | /**
|
||
618 | * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
|
||
619 | * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
|
||
620 | * calcula todas! . En este caso no importa el valor de
|
||
621 | * vbDesplazAIzquierda
|
||
622 | *
|
||
623 | * @param rVectorDatos Datos
|
||
624 | * @param raClases Clases encontradas
|
||
625 | * @param rlaIndicesRuptura �ndices de ruptura
|
||
626 | * @param vdSDAM suma de la desviaci�n standard.
|
||
627 | * @param rdGVF Desviaci�n standard de los intervalos.
|
||
628 | * @param vlIndiceRupturaActual �ndice de ruptura actual.
|
||
629 | *
|
||
630 | * @return True si se ha calcula do correctamente.
|
||
631 | */
|
||
632 | /*private boolean mbCalcularGVF(ArrayList rVectorDatos,
|
||
633 | udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
|
||
634 | double[] rdGVF, int vlIndiceRupturaActual ) {
|
||
635 | return mbCalcularGVF(rVectorDatos, raClases, rlaIndicesRuptura, vdSDAM,
|
||
636 | rdGVF, vlIndiceRupturaActual, true);
|
||
637 | }
|
||
638 | */
|
||
639 | /**
|
||
640 | * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
|
||
641 | * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
|
||
642 | * calcula todas! . En este caso no importa el valor de
|
||
643 | * vbDesplazAIzquierda
|
||
644 | *
|
||
645 | * @param rVectorDatos Datos
|
||
646 | * @param raClases Calses que representan a los intervalos.
|
||
647 | * @param rlaIndicesRuptura �ndices de ruptura.
|
||
648 | * @param vdSDAM Desviaci�n standard.
|
||
649 | * @param rdGVF Desviaci�n standard de los intervalos.
|
||
650 | * @param vlIndiceRupturaActual �ndice de ruptura actual.
|
||
651 | * @param vbDesplazAIzquierda Desplazamiento a la izquierda.
|
||
652 | *
|
||
653 | * @return True si se ha calculado correctamente.
|
||
654 | */
|
||
655 | private boolean mbCalcularGVF(List<udtDatosEstudio> rVectorDatos, |
||
656 | udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM, |
||
657 | double[] rdGVF, int vlIndiceRupturaActual /* As Long = -1*/, |
||
658 | boolean vbDesplazAIzquierda) {
|
||
659 | double ldSDCM_aux;
|
||
660 | |||
661 | int i;
|
||
662 | |||
663 | if (vlIndiceRupturaActual == -1) { |
||
664 | // 'Obtenemos los datos para todas las clases = intervalos
|
||
665 | for (i = 0; i < rlaIndicesRuptura.length; i++) { |
||
666 | if (i == 0) { // LBound(rlaIndicesRuptura) Then |
||
667 | |||
668 | if (!mbGetDatosClase(rVectorDatos, 0, rlaIndicesRuptura[i], |
||
669 | raClases, i)) { |
||
670 | return false; |
||
671 | } |
||
672 | } else {
|
||
673 | if (!mbGetDatosClase(rVectorDatos,
|
||
674 | rlaIndicesRuptura[i - 1] + 1, |
||
675 | rlaIndicesRuptura[i], raClases, i)) { |
||
676 | return false; |
||
677 | } |
||
678 | } |
||
679 | } |
||
680 | |||
681 | //'Falta la �ltima clase
|
||
682 | if (!mbGetDatosClase(rVectorDatos,
|
||
683 | rlaIndicesRuptura[rlaIndicesRuptura.length - 1] + 1, |
||
684 | rVectorDatos.size() - 1, raClases, raClases.length - 1)) { |
||
685 | return false; |
||
686 | } |
||
687 | } else {
|
||
688 | i = vlIndiceRupturaActual; |
||
689 | |||
690 | //'Hay que determinar para qu� clases debemos volver a recalcular los datos en funci�n del �ndice de ruptura que estamos modificando
|
||
691 | if (vbDesplazAIzquierda) {
|
||
692 | // 'Recalcular los datos de la clase izquierda
|
||
693 | if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
|
||
694 | rlaIndicesRuptura[i] + 1, vdSDAM, false)) { |
||
695 | return false; |
||
696 | } |
||
697 | |||
698 | // 'Recalcular los datos de la clase derecha
|
||
699 | if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos, |
||
700 | rlaIndicesRuptura[i] + 1, vdSDAM, true)) { |
||
701 | return false; |
||
702 | } |
||
703 | } else {
|
||
704 | // 'Recalcular los datos de la clase izquierda
|
||
705 | if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
|
||
706 | rlaIndicesRuptura[i], vdSDAM, true)) {
|
||
707 | return false; |
||
708 | } |
||
709 | |||
710 | // 'Recalcular los datos de la clase derecha
|
||
711 | if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos, |
||
712 | rlaIndicesRuptura[i], vdSDAM, false)) {
|
||
713 | return false; |
||
714 | } |
||
715 | } |
||
716 | } |
||
717 | |||
718 | ldSDCM_aux = 0;
|
||
719 | |||
720 | for (i = 0; i < raClases.length; i++) { //LBound(raClases) To UBound(raClases) |
||
721 | ldSDCM_aux = ldSDCM_aux + raClases[i].SDCM; |
||
722 | } |
||
723 | |||
724 | rdGVF[0] = (vdSDAM - ldSDCM_aux) / vdSDAM;
|
||
725 | //System.out.println(ldSDCM_aux);
|
||
726 | |||
727 | return true; |
||
728 | } |
||
729 | |||
730 | /**
|
||
731 | * Devuelve la "SDCM" de un conjunto de datos que vienen almacenados en el
|
||
732 | * vector rVectorDatos y que est�n delimitados por vlLimiteInf y
|
||
733 | * vlLimiteInf
|
||
734 | *
|
||
735 | * @param rVectorDatos Datos
|
||
736 | * @param vlLimiteInf L�mite inferior.
|
||
737 | * @param vlLimiteSup L�mite superior.
|
||
738 | * @param rClase Calses que representan a los intervalos.
|
||
739 | * @param numClas N�mero de calses.
|
||
740 | *
|
||
741 | * @return True si se ha calculado correctamente.
|
||
742 | */
|
||
743 | private boolean mbGetDatosClase(List<udtDatosEstudio> rVectorDatos, |
||
744 | int vlLimiteInf,
|
||
745 | int vlLimiteSup, udtDatosClase[] rClase, int numClas) { |
||
746 | int i;
|
||
747 | |||
748 | if (vlLimiteInf < 0) { |
||
749 | return false; |
||
750 | } |
||
751 | |||
752 | if (vlLimiteSup > rVectorDatos.size()) {
|
||
753 | return false; |
||
754 | } |
||
755 | |||
756 | if (vlLimiteSup < vlLimiteInf) {
|
||
757 | return false; |
||
758 | } |
||
759 | |||
760 | // 'Inicializamos los datos de la clase
|
||
761 | rClase[numClas] = new udtDatosClase();
|
||
762 | |||
763 | //'Hallamos la media de la clase
|
||
764 | for (i = vlLimiteInf; i < (vlLimiteSup + 1); i++) { |
||
765 | rClase[numClas].NumElementos = rClase[numClas].NumElementos + |
||
766 | ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias; |
||
767 | |||
768 | //'rClase.Media = rClase.Media + (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
|
||
769 | rClase[numClas].SumaTotal = rClase[numClas].SumaTotal + |
||
770 | (((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias); |
||
771 | |||
772 | //'rClase.ProductoTotal = rClase.ProductoTotal * (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
|
||
773 | rClase[numClas].SumaCuadradoTotal = rClase[numClas].SumaCuadradoTotal + |
||
774 | (Math.pow(((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(
|
||
775 | i)).Coincidencias, 2));
|
||
776 | } |
||
777 | |||
778 | //'rClase.Media = rClase.Media / llTotalElementos
|
||
779 | rClase[numClas].Media = rClase[numClas].SumaTotal / rClase[numClas].NumElementos; |
||
780 | rClase[numClas].SDCM = (rClase[numClas].SumaCuadradoTotal) - |
||
781 | (2 * rClase[numClas].Media * rClase[numClas].SumaTotal) +
|
||
782 | (rClase[numClas].NumElementos * Math.pow(rClase[numClas].Media, 2)); |
||
783 | /*if (new Double(rClase[numClas].SDCM).isNaN()){
|
||
784 | System.out.println(rClase[numClas].SDCM);
|
||
785 | }*/
|
||
786 | return true; |
||
787 | } |
||
788 | |||
789 | /**
|
||
790 | * Recalcula los datos de las clases.
|
||
791 | *
|
||
792 | * @param rClase Clases.
|
||
793 | * @param i �adir �adir �adir �adir indica si a la clase se le a�ade un
|
||
794 | * elemento (True) o se le quita (False)
|
||
795 | * @param rVectorDatos Datos.
|
||
796 | * @param vlIndiceElemento es el �ndice del elemento que se le va a�adir o
|
||
797 | * a quitar a la clase
|
||
798 | * @param vdSDAM desviaci�n standard.
|
||
799 | * @param vbA �adir DOCUMENT ME!
|
||
800 | *
|
||
801 | * @return True si se ha calculado correctamente.
|
||
802 | */
|
||
803 | private boolean mbRecalcularDatosClase(udtDatosClase[] rClase, int i, |
||
804 | List<udtDatosEstudio> rVectorDatos, int vlIndiceElemento, |
||
805 | double vdSDAM,
|
||
806 | boolean vbAnyadir) {
|
||
807 | double ldValor;
|
||
808 | long llNumCoincidencias;
|
||
809 | try{
|
||
810 | if (vlIndiceElemento>rVectorDatos.size()-1) { |
||
811 | return true; |
||
812 | } |
||
813 | ldValor = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Valor; |
||
814 | llNumCoincidencias = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Coincidencias; |
||
815 | |||
816 | if (vbAnyadir) {
|
||
817 | //'Actualizamos la suma total
|
||
818 | rClase[i].SumaTotal = rClase[i].SumaTotal + |
||
819 | (ldValor * llNumCoincidencias); |
||
820 | |||
821 | //'Actualizamos la suma de cuadrados total
|
||
822 | rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal + |
||
823 | (Math.pow((ldValor * llNumCoincidencias), 2)); |
||
824 | |||
825 | //'Actualizamos el producto total
|
||
826 | //'rClase.ProductoTotal = rClase.ProductoTotal * (ldValor * llNumCoincidencias)
|
||
827 | //'Actualizamos el n� de elementos
|
||
828 | rClase[i].NumElementos = rClase[i].NumElementos + |
||
829 | llNumCoincidencias; |
||
830 | } else {
|
||
831 | //'Actualizamos la suma total
|
||
832 | rClase[i].SumaTotal = rClase[i].SumaTotal - |
||
833 | (ldValor * llNumCoincidencias); |
||
834 | |||
835 | // 'Actualizamos la suma de cuadrados total
|
||
836 | rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal - |
||
837 | (Math.pow((ldValor * llNumCoincidencias), 2)); |
||
838 | |||
839 | // 'Actualizamos el producto total
|
||
840 | // 'rClase.ProductoTotal = rClase.ProductoTotal / (ldValor * llNumCoincidencias)
|
||
841 | // 'Actualizamos el n� de elementos
|
||
842 | rClase[i].NumElementos = rClase[i].NumElementos - |
||
843 | llNumCoincidencias; |
||
844 | } // 'If vbA�adir Then
|
||
845 | if (rClase[i].NumElementos<=0) { |
||
846 | rClase[i].NumElementos=1;
|
||
847 | } |
||
848 | //'Obtenemos la nueva media
|
||
849 | rClase[i].Media = rClase[i].SumaTotal / rClase[i].NumElementos; |
||
850 | |||
851 | //'Actualizamos la SDCM
|
||
852 | rClase[i].SDCM = (rClase[i].SumaCuadradoTotal) - |
||
853 | (2 * rClase[i].Media * rClase[i].SumaTotal) +
|
||
854 | (rClase[i].NumElementos * Math.pow(rClase[i].Media, 2)); |
||
855 | |||
856 | }catch (Exception e) { |
||
857 | return false; |
||
858 | } |
||
859 | return true; |
||
860 | } |
||
861 | |||
862 | /**
|
||
863 | * Devuelve el valor de ruptura seg�n el �ndice que se le pasa como
|
||
864 | * par�metro.
|
||
865 | *
|
||
866 | * @param viIndice �nidice del valor de ruptura.
|
||
867 | *
|
||
868 | * @return Valor de ruptura.
|
||
869 | */
|
||
870 | public double getValorRuptura(int viIndice) { |
||
871 | return mdaValoresRuptura[viIndice];
|
||
872 | } |
||
873 | |||
874 | /**
|
||
875 | * Devuelve el valor inicial de cada intervalo
|
||
876 | *
|
||
877 | * @param index �ndice del intervalo
|
||
878 | *
|
||
879 | * @return valor del intervalo.
|
||
880 | */
|
||
881 | public double getValInit(int index) { |
||
882 | return mdaValInit[index];
|
||
883 | } |
||
884 | |||
885 | /**
|
||
886 | * Devuelve el n�mero de intervalos que se pueden representar, no tiene
|
||
887 | * porque coincidir con el n�mero de intervalos que se piden.
|
||
888 | *
|
||
889 | * @return N�mero de intervalos calculados.
|
||
890 | */
|
||
891 | public int getNumIntervals() { |
||
892 | return miNumIntervalosGenerados;
|
||
893 | } |
||
894 | |||
895 | /**
|
||
896 | * Clase para contener los atributos Valor y coincidencias.
|
||
897 | *
|
||
898 | * @author Vicente Caballero Navarro
|
||
899 | */
|
||
900 | private class udtDatosEstudio { |
||
901 | private double Valor; // |
||
902 | private long Coincidencias; |
||
903 | } |
||
904 | |||
905 | /**
|
||
906 | * Clase para contener los atributos: N�mero de Elementos. Media.
|
||
907 | * SumaTotal. SumaCuadradoTotal. Desviaci�n standard.
|
||
908 | *
|
||
909 | * @author Vicente Caballero Navarro
|
||
910 | */
|
||
911 | private class udtDatosClase { |
||
912 | private long NumElementos; // 'N� total de elementos que hay en la clase |
||
913 | private double Media; // 'Media de la clase |
||
914 | private double SumaTotal; // 'Suma total de los elementos |
||
915 | |||
916 | //'ProductoTotal 'Producto total de los elementos '�dar� problemas de desbordamiento?
|
||
917 | private double SumaCuadradoTotal; // 'Suma del total de los cuadrados de los elementos |
||
918 | private double SDCM; // 'Suma de la desviaci�n t�pica de los elementos de la clase respecto de la media de la clase |
||
919 | } |
||
920 | } |