Statistics
| Revision:

svn-gvsig-desktop / tags / J2ME_compat_v1_2_Build_1209 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / rendering / NaturalIntervalGenerator.java @ 19509

History | View | Annotate | Download (30.6 KB)

1
/* 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.fmap.rendering;
42

    
43
import java.awt.Component;
44
import java.util.ArrayList;
45

    
46
import javax.swing.JOptionPane;
47

    
48
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
49
import com.hardcode.gdbms.engine.data.DataSource;
50
import com.hardcode.gdbms.engine.data.driver.DriverException;
51
import com.hardcode.gdbms.engine.values.DoubleValue;
52
import com.hardcode.gdbms.engine.values.FloatValue;
53
import com.hardcode.gdbms.engine.values.IntValue;
54
import com.hardcode.gdbms.engine.values.LongValue;
55
import com.hardcode.gdbms.engine.values.NullValue;
56
import com.hardcode.gdbms.engine.values.ShortValue;
57
import com.hardcode.gdbms.engine.values.Value;
58

    
59

    
60
/**
61
 * Calcula los intervalos naturales.
62
 *
63
 * @author Vicente Caballero Navarro
64
 */
65
public class NaturalIntervalGenerator {
66
        private DataSource ds;
67
        private String msFieldName;
68
        private int miNumIntervalosSolicitados;
69
        private int miNumIntervalosGenerados;
70
        private double[] mdaValoresRuptura;
71
        private double[] mdaValInit;
72

    
73
        /**
74
         * Crea un nuevo IntervalGenerator.
75
         *
76
         * @param layer AlphanumericData
77
         * @param field Nombre del campo.
78
         * @param numIntervals N�mero de intervalos.
79
         */
80
        public NaturalIntervalGenerator(DataSource recordSet, String field,
81
                int numIntervals) {
82
                ds = recordSet;
83
                msFieldName = field;
84
                miNumIntervalosSolicitados = numIntervals;
85
        }
86

    
87
        /**
88
         * Esta funci�n busca en el vector de datos la posici�n que le corresponde
89
         * al valor almacenado en vdValor y devuelve dicha posici�n en
90
         * vdValorAInsertar. Para hallar la posici�n se realiza una b�squeda
91
         * binaria. Si se trata de un elemento que ya est� en el vector devolvemos
92
         * el �ndice que le corresponde en rlIndiceCorrespondiente y false en
93
         * rbNuevoElemento. Si se trata de un nuevo elemento que hay que
94
         * insertar... devolvemos el �ndice en el que ir�a y True en
95
         * rbNuevoElemento En caso de que ocurra alg�n error devuelve false
96
         *
97
         * @param rVectorDatos ArrayList con los datos.
98
         * @param vdValorAInsertar Valor a insertar.
99
         * @param rlIndiceCorrespondiente �ndice.
100
         * @param rbNuevoElemento True si es un nuevo elemento.
101
         *
102
         * @return True si ha conseguido correctamente la posici�n en el vector.
103
         */
104
        private boolean mbObtenerPosicionEnVector(ArrayList rVectorDatos,
105
                double vdValorAInsertar, int[] rlIndiceCorrespondiente,
106
                boolean[] rbNuevoElemento) {
107
                int llIndiceIzq;
108
                int llIndiceDer;
109
                int llMedio;
110

    
111
                double ldValorComparacion;
112

    
113
                rbNuevoElemento[0] = false;
114
                rlIndiceCorrespondiente[0] = -1;
115

    
116
                //'Si el vector estiviese vac�o... (tuviese un s�lo elemento y el n�mero de coincidencias fuese 0)
117
                if (rVectorDatos.size() == 1) {
118
                        if (((udtDatosEstudio) rVectorDatos.get(0)).Coincidencias == 0) {
119
                                rlIndiceCorrespondiente[0] = 0;
120
                                rbNuevoElemento[0] = false; //'No tenemos que a�adir un nuevo elemento al vector
121

    
122
                                return true;
123
                        }
124
                }
125

    
126
                llIndiceIzq = 0;
127
                llIndiceDer = rVectorDatos.size() - 1;
128
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi�n entera!
129

    
130
                while (llIndiceIzq <= llIndiceDer) {
131
                        //'Coger el valor situado en la mitad de la zona de b�squeda como valor de comparaci�n
132
                        ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor;
133

    
134
                        //'Si el valor a insertar es mayor que el valor de comparaci�n...
135
                        if (vdValorAInsertar > ldValorComparacion) {
136
                                //      'La zona de b�squeda queda restringida a la parte de la derecha
137
                                llIndiceIzq = llMedio + 1;
138
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
139

    
140
                                //    'Si el valor a insertar es menor que el valor de comparaci�n...
141
                        } else if (vdValorAInsertar < ldValorComparacion) {
142
                                //          'La zona de b�squeda queda restringida a la parte de la derecha
143
                                llIndiceDer = llMedio - 1;
144
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
145

    
146
                                //        'Si el valor de comparaci�n coincide con el valor a insertar
147
                        } else if (vdValorAInsertar == ldValorComparacion) {
148
                                rlIndiceCorrespondiente[0] = llMedio;
149
                                rbNuevoElemento[0] = false;
150

    
151
                                return true;
152
                        }
153
                }
154

    
155
                //  'Si llegamos a este punto es que no hemos encontrado el valor a insertar en el vector, es decir,
156
                //  'seguro que tendremos que a�adir un nuevo elemento.
157
                rbNuevoElemento[0] = true;
158

    
159
                //  'Nota:
160
                //  'En este caso (cuando en rbNuevoElemento se devuelve True) lo que hay que hacer al salir de esta funci�n
161
                //  'es a�adir un nuevo elemento al vector y desplazar todos los valores correspondientes a partir de rlIndiceCorrespondiente
162
                //  '�D�nde va el nuevo elemento?
163
                //  'El �ltimo sitio estudiado viene dado por el valor de llMedio.
164
                //  'Si el valor a insertar es menor que el valor almacenado en la posici�n llMedio, el nuevo valor deber� ir a su izquierda.
165
                //  'Si fuera mayor deber�a ir a su derecha.
166
                ldValorComparacion = ((udtDatosEstudio) rVectorDatos.get(llMedio)).Valor;
167

    
168
                if (vdValorAInsertar > ldValorComparacion) {
169
                        rlIndiceCorrespondiente[0] = llMedio + 1;
170
                } else {
171
                        rlIndiceCorrespondiente[0] = llMedio;
172
                }
173

    
174
                return true;
175
        }
176

    
177
        /**
178
         * M�todo para generar los intervalos.
179
         *
180
         * @return true si se han generado correctamente.
181
         *
182
         * @throws com.iver.cit.gvsig.fmap.DriverException
183
         * @throws DriverException
184
         */
185
        public boolean generarIntervalos()
186
                throws ReadDriverException {
187
                ArrayList lVectorDatos;
188
                double[] ldMediaTotal = new double[1];
189
                double[] ldSDAM = new double[1];
190

    
191
                int[] llaIndicesRupturas;
192

    
193
                double[] ldUltimaGVF = new double[1];
194
                double[] ldNuevaGVF = new double[1];
195

    
196
                int i;
197
                int liNumClasesReales;
198
                int llNumElementosPorClase;
199

    
200
                //    'Obtener los datos a estudiar ordenados ascendentemente y obtener la media total
201
                //ReDim lVectorDatos(0)
202
                lVectorDatos = new ArrayList();
203

    
204
                lVectorDatos.add(new udtDatosEstudio());
205

    
206
                if (!mbObtenerDatos(lVectorDatos, ldMediaTotal)) {
207
                        return false; //SalidaSinMensaje
208
                }
209

    
210
                System.out.println("Analizando datos ...");
211

    
212
                /// Call gEstablecerDescripcionProceso("Analizando datos ...", False)
213
                //  'Calcular la suma de las desviaciones t�picas del total de los datos respecto de la media total
214
                ldSDAM[0] = mbGetSumSquaredDeviationArrayMean(lVectorDatos,
215
                                ldMediaTotal[0]);
216

    
217
                ///if (lVectorDatos.length==0){
218
                if (lVectorDatos.isEmpty()) {
219
                        //      'S�lo se pueden generar dos intervalos -> hay un valor de ruptura
220
                        ///ReDim mdaValoresRuptura(0)
221
                        mdaValoresRuptura[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
222
                        mdaValInit[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
223
                        miNumIntervalosGenerados = 2;
224

    
225
                        return true;
226
                }
227

    
228
                //  'Calculamos el n�mero m�ximo de clases reales que podemos generar.
229
                //  'Este n�mero ser�a igual al n� de elementos que tenga el vector de datos.
230
                if (miNumIntervalosSolicitados > (lVectorDatos.size())) {
231
                        liNumClasesReales = lVectorDatos.size() + 1;
232
                } else {
233
                        liNumClasesReales = miNumIntervalosSolicitados;
234
                }
235

    
236
                //  'Establecemos las clases iniciales especificando unos �ndices de ruptura en ppo. equidistantes
237
                llaIndicesRupturas = new int[liNumClasesReales - 1];
238
                llNumElementosPorClase = (lVectorDatos.size()) / liNumClasesReales;
239

    
240
                for (i = 0; i < llaIndicesRupturas.length; i++) {
241
                        if (i == 0) {
242
                                llaIndicesRupturas[i] = llNumElementosPorClase - 1;
243
                        } else {
244
                                llaIndicesRupturas[i] = llaIndicesRupturas[i - 1] +
245
                                        llNumElementosPorClase;
246
                        }
247
                }
248

    
249
                udtDatosClase[] ldaSDCM_Parciales = new udtDatosClase[llaIndicesRupturas.length +
250
                        1];
251
                udtDatosClase[] ldaSDCM_Validos = new udtDatosClase[llaIndicesRupturas.length +
252
                        1];
253

    
254
                ///ReDim ldaSDCM_Parciales(UBound(llaIndicesRupturas()) + 1)
255
                ///ReDim ldaSDCM_Validos(UBound(ldaSDCM_Parciales()) + 1)
256
                if (llaIndicesRupturas.length == 0) {
257
                        return true;
258
                }
259

    
260
                //  'Calcular la bondad inicial
261
                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales, llaIndicesRupturas,
262
                                        ldSDAM[0], ldUltimaGVF, -1, false)) {
263
//                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"el_numero_maximo_de_intervalos_para_este_campo_es")+": "+lVectorDatos.size());
264
                        miNumIntervalosSolicitados=lVectorDatos.size();
265
                        generarIntervalos();
266
                        return false;
267
                }
268

    
269
                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
270

    
271
                boolean lbMoverADerecha;
272
                boolean lbMoverAIzquierda;
273
                boolean lbIntentarDesplazamiento;
274
                int llIndiceRupturaOriginal;
275

    
276
                long k;
277
                double ldGVFentrepasadas;
278

    
279
                ldGVFentrepasadas = ldUltimaGVF[0];
280

    
281
                //'liNumClasesReales no ser� muy grande (11 es el m�ximo)
282
                for (k = 1; k <= 100; k++) {
283
                        //      'Para cada �ndice de ruptura...
284
                        for (i = 0; i < (llaIndicesRupturas.length); i++) {
285
                                lbMoverADerecha = false;
286
                                lbMoverAIzquierda = false;
287
                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
288
                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
289

    
290
                                //'Hay que decidir hacia donde hay que desplazar el �ndice de ruptura
291
                                //'Probamos moviendo a derecha (si se puede)
292
                                lbIntentarDesplazamiento = false;
293

    
294
                                if (i == (llaIndicesRupturas.length - 1)) {
295
                                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
296
                                                lbIntentarDesplazamiento = true;
297
                                        }
298
                                } else {
299
                                        if ((llaIndicesRupturas[i] + 1) < llaIndicesRupturas[i + 1]) {
300
                                                lbIntentarDesplazamiento = true;
301
                                        } //'If (llaIndicesRupturas(i) + 1) < llaIndicesRupturas(i + 1) Then
302
                                } //'If i = UBound(llaIndicesRupturas) Then
303

    
304
                                if (lbIntentarDesplazamiento) {
305
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
306

    
307
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
308
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
309
                                                                false)) {
310
                                                return false;
311
                                        }
312

    
313
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
314
                                                lbMoverADerecha = true;
315
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
316
                                        } else {
317
                                                //'Dejamos el �ndice de ruputura como estaba y probamos con un desplazamiento a izquierda
318
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
319
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
320
                                        }
321
                                } //'If lbIntentarDesplazamiento Then
322

    
323
                                lbIntentarDesplazamiento = false;
324

    
325
                                //'Probamos moviendo a izquierda (si se puede y no estamos moviendo ya a derechas)
326
                                if (!lbMoverADerecha) {
327
                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
328

    
329
                                                if ((llaIndicesRupturas[i] - 1) >= 0) { //LBound(lVectorDatos()) Then
330
                                                        lbIntentarDesplazamiento = true;
331
                                                } //'If (llaIndicesRupturas(i) - 1) >= LBound(lVectorDatos()) Then
332
                                        } else {
333
                                                if ((llaIndicesRupturas[i] - 1) > llaIndicesRupturas[i -
334
                                                                1]) {
335
                                                        lbIntentarDesplazamiento = true;
336
                                                } //'If (llaIndicesRupturas(i) - 1) > llaIndicesRupturas(i - 1) Then
337
                                        } //'If i = LBound(llaIndicesRupturas) Then
338
                                } //'If Not lbMoverADerecha Then
339

    
340
                                if (lbIntentarDesplazamiento) {
341
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1;
342

    
343
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
344
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
345
                                                                true)) {
346
                                                return false;
347
                                        }
348

    
349
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
350
                                                lbMoverAIzquierda = true;
351
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
352
                                        } else {
353
                                                //'Dejamos el �ndice de ruputura como estaba
354
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
355
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
356
                                        }
357
                                } //'If lbIntentarDesplazamiento Then
358

    
359
                                lbIntentarDesplazamiento = false;
360

    
361
                                //'Si se ha decidido desplazar el �ndice ... continuamos hasta que no podamos mejorar la GVF
362
                                if (lbMoverAIzquierda || lbMoverADerecha) {
363
                                        ldUltimaGVF[0] = ldNuevaGVF[0];
364

    
365
                                        boolean exit = false;
366

    
367
                                        while (!exit) {
368
                                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
369

    
370
                                                if (lbMoverADerecha) {
371
                                                        if (i == (llaIndicesRupturas.length - 1)) {
372
                                                                if ((llaIndicesRupturas[i] + 1) >= lVectorDatos.size()) {
373
                                                                        exit = true;
374
                                                                }
375
                                                        } else {
376
                                                                if ((llaIndicesRupturas[i] + 1) >= llaIndicesRupturas[i +
377
                                                                                1]) {
378
                                                                        exit = true;
379
                                                                }
380
                                                        } //'If i = UBound(llaIndicesRupturas) Then
381

    
382
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
383
                                                } else { //'If lbMoverAIzquierda Then
384

    
385
                                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
386

    
387
                                                                if ((llaIndicesRupturas[i] - 1) < 0) { //LBound(lVectorDatos()) Then Exit Do
388
                                                                        exit = true;
389
                                                                }
390
                                                        } else {
391
                                                                if ((llaIndicesRupturas[i] - 1) <= llaIndicesRupturas[i -
392
                                                                                1]) {
393
                                                                        exit = true;
394
                                                                }
395
                                                        } //'If i = LBound(llaIndicesRupturas) Then
396

    
397
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1; //////////////////
398
                                                } //'If lbMoverADerecha Then
399

    
400
                                                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
401
                                                                        llaIndicesRupturas, ldSDAM[0], ldNuevaGVF,
402
                                                                        i, lbMoverAIzquierda)) {
403
                                                        return false;
404
                                                }
405

    
406
                                                if (ldNuevaGVF[0] < ldUltimaGVF[0]) {
407
                                                        // 'Dejar el �ndice donde estaba
408
                                                        llaIndicesRupturas[i] = llIndiceRupturaOriginal;
409
                                                        ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
410
                                                        exit = true;
411
                                                } else {
412
                                                        ldUltimaGVF[0] = ldNuevaGVF[0];
413
                                                        ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
414
                                                }
415
                                        }
416
                                } //'If lbMoverAIzquierda Or lbMoverADerecha Then
417
                        }
418

    
419
                        if (ldUltimaGVF[0] <= ldGVFentrepasadas) {
420
                                i = 101;
421
                        }
422

    
423
                        ldGVFentrepasadas = ldUltimaGVF[0];
424
                }
425

    
426
                //   'A partir de aqu� ya no se puede cancelar nada
427
                mdaValoresRuptura = new double[llaIndicesRupturas.length];
428
                mdaValInit = new double[llaIndicesRupturas.length];
429

    
430
                for (i = 0; i < mdaValoresRuptura.length; i++) { // LBound(mdaValoresRuptura) To UBound(mdaValoresRuptura)
431
                        if (llaIndicesRupturas[i]==-1)llaIndicesRupturas[i]=1;
432
                        if (llaIndicesRupturas[i]>lVectorDatos.size()-1)llaIndicesRupturas[i]=lVectorDatos.size()-1;
433
                        mdaValoresRuptura[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
434

    
435
                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
436
                                mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i] +
437
                                                1)).Valor;
438
                        } else {
439
                                mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
440
                        }
441

    
442
                        //      'Hay que aplicar una peque�a correcci�n a los valores de ruptura para que los intervalos que genera
443
                        //    'mapobjects se aprechen en su totalidad, o lo que es lo mismo, vengan todos representados en el mapa.
444
                        //  'Con esto tambi�n se consigue hallar intervalos equivalentes a los de ArcView. Esta correcci�n consiste
445
                        //'en sumar el m�nimo incremento a los valores de ruptura. No lo hago aqu� sino en la ventana de propiedades de capa.
446
                }
447

    
448
                miNumIntervalosGenerados = mdaValoresRuptura.length + 2;
449

    
450
                ldaSDCM_Validos = null;
451
                ldaSDCM_Parciales = null;
452
                lVectorDatos = null;
453

    
454
                return true;
455
        }
456

    
457
        /**
458
         * DOCUMENT ME!
459
         *
460
         * @param array DOCUMENT ME!
461
         *
462
         * @return DOCUMENT ME!
463
         */
464
        private udtDatosClase[] getArray(udtDatosClase[] array) {
465
                udtDatosClase[] aux = new udtDatosClase[array.length];
466

    
467
                for (int i = 0; i < array.length; i++) {
468
                        aux[i] = new udtDatosClase();
469
                        aux[i].Media = array[i].Media;
470
                        aux[i].NumElementos = array[i].NumElementos;
471
                        aux[i].SDCM = array[i].SDCM;
472
                        aux[i].SumaCuadradoTotal = array[i].SumaCuadradoTotal;
473
                        aux[i].SumaTotal = array[i].SumaTotal;
474
                }
475

    
476
                return aux;
477
        }
478

    
479
        /**
480
         * Devuelve la "SDAM" de un conjunto de datos que vienen almacenados en el
481
         * vector rVectorDatos
482
         *
483
         * @param rVectorDatos Datos
484
         * @param vdMedia Media
485
         *
486
         * @return suma de las desviaciones t�picas del total de los datos respecto
487
         *                    de la media total
488
         */
489
        private double mbGetSumSquaredDeviationArrayMean(ArrayList rVectorDatos,
490
                double vdMedia) {
491
                int i;
492

    
493
                double rdSDAM = 0;
494

    
495
                for (i = 0; i < rVectorDatos.size(); i++) { // LBound(rVectorDatos) To UBound(rVectorDatos)
496
                        rdSDAM = rdSDAM +
497
                                (Math.pow((((udtDatosEstudio) rVectorDatos.get(i)).Valor -
498
                                        vdMedia), 2) * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
499
                }
500

    
501
                return rdSDAM;
502
        }
503

    
504
        /**
505
         * Esta funci�n obtiene los datos en los que queremos hallar las rupturas
506
         * naturales. Los datos se devuelven ordenados en un vector. Tambi�n
507
         * devuelve la media total
508
         *
509
         * @param rVectorDatos Datos
510
         * @param rdMediaTotal Media total
511
         *
512
         * @return True si se ha calculado correctamente.
513
         *
514
         * @throws com.iver.cit.gvsig.fmap.DriverException
515
         * @throws DriverException
516
         */
517
        private boolean mbObtenerDatos(ArrayList rVectorDatos, double[] rdMediaTotal)
518
                throws ReadDriverException {
519
                double ldValor;
520

    
521
                int i;
522
                long llRecordCount;
523

    
524
                int[] llIndice = new int[1];
525
                boolean[] lbNuevoElemento = new boolean[1];
526
                //int j;
527

    
528
                llRecordCount = ds.getRowCount();
529

    
530
                if (!gbExisteCampoEnRegistro(ds, msFieldName)) {
531
                        if (msFieldName == "") {
532
                                System.out.println(
533
                                        "No se ha establecido el nombre del campo origen!");
534
                        } else {
535
                                System.out.println("El campo '" + msFieldName +
536
                                        "' no pertence a la capa!");
537
                        }
538

    
539
                        return false;
540
                }
541

    
542
                // 'Nos cuidamos de recorrer todos los registros sin consultar la propiedad EOF del recordset
543
                for (i = 0; i < llRecordCount; i++) {
544
                        try{
545
                                ldValor =  getValue(ds.getFieldValue(i,
546
                                                        ds.getFieldIndexByName(msFieldName)));
547
                        }catch (Exception e) {
548
                                llRecordCount--;
549
                                continue;
550
                        }
551
                        rdMediaTotal[0] = rdMediaTotal[0] + ldValor;
552

    
553
                        //       'Hay que insertar el valor en la posici�n adecuada. Para ello hacemos una b�squeda binaria
554
                        if (!mbObtenerPosicionEnVector(rVectorDatos, ldValor, llIndice,
555
                                                lbNuevoElemento)) {
556
                                return false;
557
                        }
558

    
559
                        if (!lbNuevoElemento[0]) {
560
                                if ((llIndice[0] < 0) || (llIndice[0] > rVectorDatos.size())) {
561
                                        System.out.println("�ndice incorrecto!");
562

    
563
                                        return false;
564
                                }
565

    
566
                                ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Valor = ldValor; //'Por si fuese el primer elemento
567

    
568
                                //'Incrementamos el n� de coincidencias y damos el valor por insertado
569
                                ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias = ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias +
570
                                        1;
571
                        } else {
572
                                udtDatosEstudio udt = new udtDatosEstudio();
573
                                udt.Valor = ldValor;
574
                                udt.Coincidencias = 1;
575
                                rVectorDatos.add(llIndice[0], udt);
576
                        }
577
                }
578

    
579
                rdMediaTotal[0] = rdMediaTotal[0] / llRecordCount;
580

    
581
                return true;
582
        }
583

    
584
        /**
585
         * Devuelve true si existe el campo en el registro.
586
         *
587
         * @param recordset Recordset.
588
         * @param msFieldName2 Nombre del campo.
589
         *
590
         * @return True si existe el campo.
591
         * @throws ReadDriverException
592
         *
593
         */
594
        private boolean gbExisteCampoEnRegistro(DataSource recordset,
595
                String msFieldName2) throws ReadDriverException  {
596
                if (recordset.getFieldIndexByName(msFieldName2) == -1) {
597
                        return false;
598
                }
599

    
600
                return true;
601
        }
602

    
603
        /**
604
         * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
605
         * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
606
         * calcula todas! . En este caso no importa el valor de
607
         * vbDesplazAIzquierda
608
         *
609
         * @param rVectorDatos Datos
610
         * @param raClases Clases encontradas
611
         * @param rlaIndicesRuptura �ndices de ruptura
612
         * @param vdSDAM suma de la desviaci�n standard.
613
         * @param rdGVF Desviaci�n standard de los intervalos.
614
         * @param vlIndiceRupturaActual �ndice de ruptura actual.
615
         *
616
         * @return True si se ha calcula do correctamente.
617
         */
618
        /*private boolean mbCalcularGVF(ArrayList rVectorDatos,
619
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
620
                double[] rdGVF, int vlIndiceRupturaActual ) {
621
                return mbCalcularGVF(rVectorDatos, raClases, rlaIndicesRuptura, vdSDAM,
622
                        rdGVF, vlIndiceRupturaActual, true);
623
        }
624
*/
625
        /**
626
         * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
627
         * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
628
         * calcula todas! . En este caso no importa el valor de
629
         * vbDesplazAIzquierda
630
         *
631
         * @param rVectorDatos Datos
632
         * @param raClases Calses que representan a los intervalos.
633
         * @param rlaIndicesRuptura �ndices de ruptura.
634
         * @param vdSDAM Desviaci�n standard.
635
         * @param rdGVF Desviaci�n standard de los intervalos.
636
         * @param vlIndiceRupturaActual �ndice de ruptura actual.
637
         * @param vbDesplazAIzquierda Desplazamiento a la izquierda.
638
         *
639
         * @return True si se ha calculado correctamente.
640
         */
641
        private boolean mbCalcularGVF(ArrayList rVectorDatos,
642
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
643
                double[] rdGVF, int vlIndiceRupturaActual /* As Long = -1*/,
644
                boolean vbDesplazAIzquierda) {
645
                double ldSDCM_aux;
646

    
647
                int i;
648

    
649
                if (vlIndiceRupturaActual == -1) {
650
                        // 'Obtenemos los datos para todas las clases = intervalos
651
                        for (i = 0; i < rlaIndicesRuptura.length; i++) {
652
                                if (i == 0) { // LBound(rlaIndicesRuptura) Then
653

    
654
                                        if (!mbGetDatosClase(rVectorDatos, 0, rlaIndicesRuptura[i],
655
                                                                raClases, i)) {
656
                                                return false;
657
                                        }
658
                                } else {
659
                                        if (!mbGetDatosClase(rVectorDatos,
660
                                                                rlaIndicesRuptura[i - 1] + 1,
661
                                                                rlaIndicesRuptura[i], raClases, i)) {
662
                                                return false;
663
                                        }
664
                                }
665
                        }
666

    
667
                        //'Falta la �ltima clase
668
                        if (!mbGetDatosClase(rVectorDatos,
669
                                                rlaIndicesRuptura[rlaIndicesRuptura.length - 1] + 1,
670
                                                rVectorDatos.size() - 1, raClases, raClases.length - 1)) {
671
                                return false;
672
                        }
673
                } else {
674
                        i = vlIndiceRupturaActual;
675

    
676
                        //'Hay que determinar para qu� clases debemos volver a recalcular los datos en funci�n del �ndice de ruptura que estamos modificando
677
                        if (vbDesplazAIzquierda) {
678
                                //  'Recalcular los datos de la clase izquierda
679
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
680
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, false)) {
681
                                        return false;
682
                                }
683

    
684
                                //  'Recalcular los datos de la clase derecha
685
                                if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos,
686
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, true)) {
687
                                        return false;
688
                                }
689
                        } else {
690
                                //  'Recalcular los datos de la clase izquierda
691
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
692
                                                        rlaIndicesRuptura[i], vdSDAM, true)) {
693
                                        return false;
694
                                }
695

    
696
                                //  'Recalcular los datos de la clase derecha
697
                                if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos,
698
                                                        rlaIndicesRuptura[i], vdSDAM, false)) {
699
                                        return false;
700
                                }
701
                        }
702
                }
703

    
704
                ldSDCM_aux = 0;
705

    
706
                for (i = 0; i < raClases.length; i++) { //LBound(raClases) To UBound(raClases)
707
                        ldSDCM_aux = ldSDCM_aux + raClases[i].SDCM;
708
                }
709

    
710
                rdGVF[0] = (vdSDAM - ldSDCM_aux) / vdSDAM;
711
                //System.out.println(ldSDCM_aux);
712

    
713
                return true;
714
        }
715

    
716
        /**
717
         * Devuelve la "SDCM" de un conjunto de datos que vienen almacenados en el
718
         * vector rVectorDatos y que est�n delimitados por vlLimiteInf y
719
         * vlLimiteInf
720
         *
721
         * @param rVectorDatos Datos
722
         * @param vlLimiteInf L�mite inferior.
723
         * @param vlLimiteSup L�mite superior.
724
         * @param rClase Calses que representan a los intervalos.
725
         * @param numClas N�mero de calses.
726
         *
727
         * @return True si se ha calculado correctamente.
728
         */
729
        private boolean mbGetDatosClase(ArrayList rVectorDatos, int vlLimiteInf,
730
                int vlLimiteSup, udtDatosClase[] rClase, int numClas) {
731
                int i;
732

    
733
                if (vlLimiteInf < 0) {
734
                        return false;
735
                }
736

    
737
                if (vlLimiteSup > rVectorDatos.size()) {
738
                        return false;
739
                }
740

    
741
                if (vlLimiteSup < vlLimiteInf) {
742
                        return false;
743
                }
744

    
745
                // 'Inicializamos los datos de la clase
746
                rClase[numClas] = new udtDatosClase();
747

    
748
                //'Hallamos la media de la clase
749
                for (i = vlLimiteInf; i < (vlLimiteSup + 1); i++) {
750
                        rClase[numClas].NumElementos = rClase[numClas].NumElementos +
751
                                ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias;
752

    
753
                        //'rClase.Media = rClase.Media + (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
754
                        rClase[numClas].SumaTotal = rClase[numClas].SumaTotal +
755
                                (((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
756

    
757
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
758
                        rClase[numClas].SumaCuadradoTotal = rClase[numClas].SumaCuadradoTotal +
759
                                (Math.pow(((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(
760
                                                i)).Coincidencias, 2));
761
                }
762

    
763
                //'rClase.Media = rClase.Media / llTotalElementos
764
                rClase[numClas].Media = rClase[numClas].SumaTotal / rClase[numClas].NumElementos;
765
                rClase[numClas].SDCM = (rClase[numClas].SumaCuadradoTotal) -
766
                        (2 * rClase[numClas].Media * rClase[numClas].SumaTotal) +
767
                        (rClase[numClas].NumElementos * Math.pow(rClase[numClas].Media, 2));
768
                /*if (new Double(rClase[numClas].SDCM).isNaN()){
769
                        System.out.println(rClase[numClas].SDCM);
770
                }*/
771
                return true;
772
        }
773

    
774
        /**
775
         * Recalcula los datos de las clases.
776
         *
777
         * @param rClase Clases.
778
         * @param i �adir �adir �adir �adir indica si a la clase se le a�ade un
779
         *                   elemento (True) o se le quita (False)
780
         * @param rVectorDatos Datos.
781
         * @param vlIndiceElemento es el �ndice del elemento que se le va a�adir o
782
         *                   a quitar a la clase
783
         * @param vdSDAM desviaci�n standard.
784
         * @param vbA �adir DOCUMENT ME!
785
         *
786
         * @return True si se ha calculado correctamente.
787
         */
788
        private boolean mbRecalcularDatosClase(udtDatosClase[] rClase, int i,
789
                ArrayList rVectorDatos, int vlIndiceElemento, double vdSDAM,
790
                boolean vbAnyadir) {
791
                double ldValor;
792
                long llNumCoincidencias;
793
try{
794
        if (vlIndiceElemento>rVectorDatos.size()-1)return true;
795
                ldValor = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Valor;
796
                llNumCoincidencias = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Coincidencias;
797

    
798
                if (vbAnyadir) {
799
                        //'Actualizamos la suma total
800
                        rClase[i].SumaTotal = rClase[i].SumaTotal +
801
                                (ldValor * llNumCoincidencias);
802

    
803
                        //'Actualizamos la suma de cuadrados total
804
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal +
805
                                (Math.pow((ldValor * llNumCoincidencias), 2));
806

    
807
                        //'Actualizamos el producto total
808
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (ldValor * llNumCoincidencias)
809
                        //'Actualizamos el n� de elementos
810
                        rClase[i].NumElementos = rClase[i].NumElementos +
811
                                llNumCoincidencias;
812
                } else {
813
                        //'Actualizamos la suma total
814
                        rClase[i].SumaTotal = rClase[i].SumaTotal -
815
                                (ldValor * llNumCoincidencias);
816

    
817
                        // 'Actualizamos la suma de cuadrados total
818
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal -
819
                                (Math.pow((ldValor * llNumCoincidencias), 2));
820

    
821
                        // 'Actualizamos el producto total
822
                        // 'rClase.ProductoTotal = rClase.ProductoTotal / (ldValor * llNumCoincidencias)
823
                        // 'Actualizamos el n� de elementos
824
                        rClase[i].NumElementos = rClase[i].NumElementos -
825
                                llNumCoincidencias;
826
                } // 'If vbA�adir Then
827
                if (rClase[i].NumElementos<=0)rClase[i].NumElementos=1;
828
                //'Obtenemos la nueva media
829
                rClase[i].Media = rClase[i].SumaTotal / rClase[i].NumElementos;
830

    
831
                //'Actualizamos la SDCM
832
                rClase[i].SDCM = (rClase[i].SumaCuadradoTotal) -
833
                        (2 * rClase[i].Media * rClase[i].SumaTotal) +
834
                        (rClase[i].NumElementos * Math.pow(rClase[i].Media, 2));
835

    
836
}catch (Exception e) {
837
        return false;
838
}
839
                return true;
840
        }
841

    
842
        /**
843
         * Devuelve el valor de ruptura seg�n el �ndice que se le pasa como
844
         * par�metro.
845
         *
846
         * @param viIndice �nidice del valor de ruptura.
847
         *
848
         * @return Valor de ruptura.
849
         */
850
        public double getValorRuptura(int viIndice) {
851
                return mdaValoresRuptura[viIndice];
852
        }
853

    
854
        /**
855
         * Devuelve el valor inicial de cada intervalo
856
         *
857
         * @param index �ndice del intervalo
858
         *
859
         * @return valor del intervalo.
860
         */
861
        public double getValInit(int index) {
862
                return mdaValInit[index];
863
        }
864

    
865
        /**
866
         * Devuelve el n�mero de intervalos que se pueden representar, no tiene
867
         * porque coincidir con el n�mero de intervalos que se piden.
868
         *
869
         * @return N�mero de intervalos calculados.
870
         */
871
        public int getNumIntervals() {
872
                return miNumIntervalosGenerados;
873
        }
874

    
875
        /**
876
         * Clase para contener los atributos Valor y coincidencias.
877
         *
878
         * @author Vicente Caballero Navarro
879
         */
880
        private class udtDatosEstudio {
881
                private double Valor; //
882
                private long Coincidencias;
883
        }
884

    
885
        /**
886
         * Clase para contener los atributos: N�mero de Elementos. Media.
887
         * SumaTotal. SumaCuadradoTotal. Desviaci�n standard.
888
         *
889
         * @author Vicente Caballero Navarro
890
         */
891
        private class udtDatosClase {
892
                private long NumElementos; //             'N� total de elementos que hay en la clase
893
                private double Media; //                 'Media de la clase
894
                private double SumaTotal; //              'Suma total de los elementos
895

    
896
                //'ProductoTotal          'Producto total de los elementos '�dar� problemas de desbordamiento?
897
                private double SumaCuadradoTotal; //      'Suma del total de los cuadrados de los elementos
898
                private double SDCM; //                  'Suma de la desviaci�n t�pica de los elementos de la clase respecto de la media de la clase
899
        }
900
        /**
901
         * Devuelve el valor en un double del Value que se pasa como par�metro.
902
         *
903
         * @param value Value.
904
         *
905
         * @return valor.
906
         * @throws Exception
907
         */
908
        private double getValue(Value value) throws Exception {
909
                if (value instanceof IntValue) {
910
                        return ((IntValue) value).intValue();
911
                } else if (value instanceof LongValue) {
912
                        return ((LongValue) value).longValue();
913
                } else if (value instanceof FloatValue) {
914
                        return ((FloatValue) value).floatValue();
915
                } else if (value instanceof ShortValue) {
916
                        return ((ShortValue) value).shortValue();
917
                } else if (value instanceof NullValue){
918
                        throw new Exception();
919
                }
920

    
921
                return ((DoubleValue) value).doubleValue();
922
        }
923
}