Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / NaturalIntervalGenerator.java @ 7738

History | View | Annotate | Download (29.9 KB)

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