Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.symbology / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / impl / NaturalIntervalGenerator.java @ 33205

History | View | Annotate | Download (30.4 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 org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl;
42

    
43
import java.util.ArrayList;
44
import java.util.List;
45

    
46
import org.gvsig.fmap.dal.exception.DataException;
47
import org.gvsig.tools.dispose.DisposableIterator;
48
import org.gvsig.fmap.dal.feature.Feature;
49
import org.gvsig.fmap.dal.feature.FeatureQuery;
50
import org.gvsig.fmap.dal.feature.FeatureSet;
51
import org.gvsig.fmap.dal.feature.FeatureStore;
52
import org.gvsig.fmap.dal.feature.FeatureType;
53

    
54
/**
55
 * Calcula los intervalos naturales.
56
 *
57
 * @author Vicente Caballero Navarro
58
 */
59
public class NaturalIntervalGenerator {
60
//        private DataSource ds;
61
        private String msFieldName;
62
        private int miNumIntervalosSolicitados;
63
        private int miNumIntervalosGenerados;
64
        private double[] mdaValoresRuptura;
65
        private double[] mdaValInit;
66
        private FeatureStore featureStore;
67

    
68
        /**
69
         * Crea un nuevo IntervalGenerator.
70
         *
71
         * @param layer AlphanumericData
72
         * @param field Nombre del campo.
73
         * @param numIntervals N�mero de intervalos.
74
         */
75
        public NaturalIntervalGenerator(FeatureStore fs, String field,
76
                int numIntervals) {
77
                featureStore = fs;
78
                msFieldName = field;
79
                miNumIntervalosSolicitados = numIntervals;
80
        }
81

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

    
107
                double ldValorComparacion;
108

    
109
                rbNuevoElemento[0] = false;
110
                rlIndiceCorrespondiente[0] = -1;
111

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

    
118
                                return true;
119
                        }
120
                }
121

    
122
                llIndiceIzq = 0;
123
                llIndiceDer = rVectorDatos.size() - 1;
124
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi�n entera!
125

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

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

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

    
142
                                //        'Si el valor de comparaci�n coincide con el valor a insertar
143
                        } else if (vdValorAInsertar == ldValorComparacion) {
144
                                rlIndiceCorrespondiente[0] = llMedio;
145
                                rbNuevoElemento[0] = false;
146

    
147
                                return true;
148
                        }
149
                }
150

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

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

    
164
                if (vdValorAInsertar > ldValorComparacion) {
165
                        rlIndiceCorrespondiente[0] = llMedio + 1;
166
                } else {
167
                        rlIndiceCorrespondiente[0] = llMedio;
168
                }
169

    
170
                return true;
171
        }
172

    
173
        /**
174
         * M�todo para generar los intervalos.
175
         *
176
         * @return true si se han generado correctamente.
177
         * @throws DataException TODO
178
         */
179
        public boolean generarIntervalos()
180
                throws DataException {
181
                List<udtDatosEstudio> lVectorDatos;
182
                double[] ldMediaTotal = new double[1];
183
                double[] ldSDAM = new double[1];
184

    
185
                int[] llaIndicesRupturas;
186

    
187
                double[] ldUltimaGVF = new double[1];
188
                double[] ldNuevaGVF = new double[1];
189

    
190
                int i;
191
                int liNumClasesReales;
192
                int llNumElementosPorClase;
193

    
194
                //    'Obtener los datos a estudiar ordenados ascendentemente y obtener la media total
195
                //ReDim lVectorDatos(0)
196
                lVectorDatos = new ArrayList<udtDatosEstudio>();
197

    
198
                lVectorDatos.add(new udtDatosEstudio());
199

    
200
                if (!mbObtenerDatos(lVectorDatos, ldMediaTotal)) {
201
                        return false; //SalidaSinMensaje
202
                }
203

    
204
                System.out.println("Analizando datos ...");
205

    
206
                /// Call gEstablecerDescripcionProceso("Analizando datos ...", False)
207
                //  'Calcular la suma de las desviaciones t�picas del total de los datos respecto de la media total
208
                ldSDAM[0] = mbGetSumSquaredDeviationArrayMean(lVectorDatos,
209
                                ldMediaTotal[0]);
210

    
211
                ///if (lVectorDatos.length==0){
212
                if (lVectorDatos.isEmpty()) {
213
                        //      'S�lo se pueden generar dos intervalos -> hay un valor de ruptura
214
                        ///ReDim mdaValoresRuptura(0)
215
                        mdaValoresRuptura[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
216
                        mdaValInit[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
217
                        miNumIntervalosGenerados = 2;
218

    
219
                        return true;
220
                }
221

    
222
                //  'Calculamos el n�mero m�ximo de clases reales que podemos generar.
223
                //  'Este n�mero ser�a igual al n� de elementos que tenga el vector de datos.
224
                if (miNumIntervalosSolicitados > (lVectorDatos.size())) {
225
                        liNumClasesReales = lVectorDatos.size() + 1;
226
                } else {
227
                        liNumClasesReales = miNumIntervalosSolicitados;
228
                }
229

    
230
                //  'Establecemos las clases iniciales especificando unos �ndices de ruptura en ppo. equidistantes
231
                llaIndicesRupturas = new int[liNumClasesReales - 1];
232
                llNumElementosPorClase = (lVectorDatos.size()) / liNumClasesReales;
233

    
234
                for (i = 0; i < llaIndicesRupturas.length; i++) {
235
                        if (i == 0) {
236
                                llaIndicesRupturas[i] = llNumElementosPorClase - 1;
237
                        } else {
238
                                llaIndicesRupturas[i] = llaIndicesRupturas[i - 1] +
239
                                        llNumElementosPorClase;
240
                        }
241
                }
242

    
243
                udtDatosClase[] ldaSDCM_Parciales = new udtDatosClase[llaIndicesRupturas.length +
244
                        1];
245
                udtDatosClase[] ldaSDCM_Validos = new udtDatosClase[llaIndicesRupturas.length +
246
                        1];
247

    
248
                ///ReDim ldaSDCM_Parciales(UBound(llaIndicesRupturas()) + 1)
249
                ///ReDim ldaSDCM_Validos(UBound(ldaSDCM_Parciales()) + 1)
250
                if (llaIndicesRupturas.length == 0) {
251
                        return true;
252
                }
253

    
254
                //  'Calcular la bondad inicial
255
                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales, llaIndicesRupturas,
256
                                        ldSDAM[0], ldUltimaGVF, -1, false)) {
257
//                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"el_numero_maximo_de_intervalos_para_este_campo_es")+": "+lVectorDatos.size());
258
                        miNumIntervalosSolicitados=lVectorDatos.size();
259
                        generarIntervalos();
260
                        return false;
261
                }
262

    
263
                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
264

    
265
                boolean lbMoverADerecha;
266
                boolean lbMoverAIzquierda;
267
                boolean lbIntentarDesplazamiento;
268
                int llIndiceRupturaOriginal;
269

    
270
                long k;
271
                double ldGVFentrepasadas;
272

    
273
                ldGVFentrepasadas = ldUltimaGVF[0];
274

    
275
                //'liNumClasesReales no ser� muy grande (11 es el m�ximo)
276
                for (k = 1; k <= 100; k++) {
277
                        //      'Para cada �ndice de ruptura...
278
                        for (i = 0; i < (llaIndicesRupturas.length); i++) {
279
                                lbMoverADerecha = false;
280
                                lbMoverAIzquierda = false;
281
                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
282
                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
283

    
284
                                //'Hay que decidir hacia donde hay que desplazar el �ndice de ruptura
285
                                //'Probamos moviendo a derecha (si se puede)
286
                                lbIntentarDesplazamiento = false;
287

    
288
                                if (i == (llaIndicesRupturas.length - 1)) {
289
                                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
290
                                                lbIntentarDesplazamiento = true;
291
                                        }
292
                                } else {
293
                                        if ((llaIndicesRupturas[i] + 1) < llaIndicesRupturas[i + 1]) {
294
                                                lbIntentarDesplazamiento = true;
295
                                        } //'If (llaIndicesRupturas(i) + 1) < llaIndicesRupturas(i + 1) Then
296
                                } //'If i = UBound(llaIndicesRupturas) Then
297

    
298
                                if (lbIntentarDesplazamiento) {
299
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
300

    
301
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
302
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
303
                                                                false)) {
304
                                                return false;
305
                                        }
306

    
307
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
308
                                                lbMoverADerecha = true;
309
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
310
                                        } else {
311
                                                //'Dejamos el �ndice de ruputura como estaba y probamos con un desplazamiento a izquierda
312
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
313
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
314
                                        }
315
                                } //'If lbIntentarDesplazamiento Then
316

    
317
                                lbIntentarDesplazamiento = false;
318

    
319
                                //'Probamos moviendo a izquierda (si se puede y no estamos moviendo ya a derechas)
320
                                if (!lbMoverADerecha) {
321
                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
322

    
323
                                                if ((llaIndicesRupturas[i] - 1) >= 0) { //LBound(lVectorDatos()) Then
324
                                                        lbIntentarDesplazamiento = true;
325
                                                } //'If (llaIndicesRupturas(i) - 1) >= LBound(lVectorDatos()) Then
326
                                        } else {
327
                                                if ((llaIndicesRupturas[i] - 1) > llaIndicesRupturas[i -
328
                                                                1]) {
329
                                                        lbIntentarDesplazamiento = true;
330
                                                } //'If (llaIndicesRupturas(i) - 1) > llaIndicesRupturas(i - 1) Then
331
                                        } //'If i = LBound(llaIndicesRupturas) Then
332
                                } //'If Not lbMoverADerecha Then
333

    
334
                                if (lbIntentarDesplazamiento) {
335
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1;
336

    
337
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
338
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
339
                                                                true)) {
340
                                                return false;
341
                                        }
342

    
343
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
344
                                                lbMoverAIzquierda = true;
345
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
346
                                        } else {
347
                                                //'Dejamos el �ndice de ruputura como estaba
348
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
349
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
350
                                        }
351
                                } //'If lbIntentarDesplazamiento Then
352

    
353
                                lbIntentarDesplazamiento = false;
354

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

    
359
                                        boolean exit = false;
360

    
361
                                        while (!exit) {
362
                                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
363

    
364
                                                if (lbMoverADerecha) {
365
                                                        if (i == (llaIndicesRupturas.length - 1)) {
366
                                                                if ((llaIndicesRupturas[i] + 1) >= lVectorDatos.size()) {
367
                                                                        exit = true;
368
                                                                }
369
                                                        } else {
370
                                                                if ((llaIndicesRupturas[i] + 1) >= llaIndicesRupturas[i +
371
                                                                                1]) {
372
                                                                        exit = true;
373
                                                                }
374
                                                        } //'If i = UBound(llaIndicesRupturas) Then
375

    
376
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
377
                                                } else { //'If lbMoverAIzquierda Then
378

    
379
                                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
380

    
381
                                                                if ((llaIndicesRupturas[i] - 1) < 0) { //LBound(lVectorDatos()) Then Exit Do
382
                                                                        exit = true;
383
                                                                }
384
                                                        } else {
385
                                                                if ((llaIndicesRupturas[i] - 1) <= llaIndicesRupturas[i -
386
                                                                                1]) {
387
                                                                        exit = true;
388
                                                                }
389
                                                        } //'If i = LBound(llaIndicesRupturas) Then
390

    
391
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1; //////////////////
392
                                                } //'If lbMoverADerecha Then
393

    
394
                                                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
395
                                                                        llaIndicesRupturas, ldSDAM[0], ldNuevaGVF,
396
                                                                        i, lbMoverAIzquierda)) {
397
                                                        return false;
398
                                                }
399

    
400
                                                if (ldNuevaGVF[0] < ldUltimaGVF[0]) {
401
                                                        // 'Dejar el �ndice donde estaba
402
                                                        llaIndicesRupturas[i] = llIndiceRupturaOriginal;
403
                                                        ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
404
                                                        exit = true;
405
                                                } else {
406
                                                        ldUltimaGVF[0] = ldNuevaGVF[0];
407
                                                        ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
408
                                                }
409
                                        }
410
                                } //'If lbMoverAIzquierda Or lbMoverADerecha Then
411
                        }
412

    
413
                        if (ldUltimaGVF[0] <= ldGVFentrepasadas) {
414
                                i = 101;
415
                        }
416

    
417
                        ldGVFentrepasadas = ldUltimaGVF[0];
418
                }
419

    
420
                //   'A partir de aqu� ya no se puede cancelar nada
421
                mdaValoresRuptura = new double[llaIndicesRupturas.length];
422
                mdaValInit = new double[llaIndicesRupturas.length];
423

    
424
                for (i = 0; i < mdaValoresRuptura.length; i++) { // LBound(mdaValoresRuptura) To UBound(mdaValoresRuptura)
425
                        if (llaIndicesRupturas[i]==-1) {
426
                                llaIndicesRupturas[i]=1;
427
                        }
428
                        if (llaIndicesRupturas[i]>lVectorDatos.size()-1) {
429
                                llaIndicesRupturas[i]=lVectorDatos.size()-1;
430
                        }
431
                        mdaValoresRuptura[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
432

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

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

    
446
                miNumIntervalosGenerados = mdaValoresRuptura.length + 2;
447

    
448
                ldaSDCM_Validos = null;
449
                ldaSDCM_Parciales = null;
450
                lVectorDatos = null;
451

    
452
                return true;
453
        }
454

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

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

    
474
                return aux;
475
        }
476

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

    
492
                double rdSDAM = 0;
493

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

    
500
                return rdSDAM;
501
        }
502

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

    
519
//                int i;
520
                long llRecordCount=0;
521

    
522
                int[] llIndice = new int[1];
523
                boolean[] lbNuevoElemento = new boolean[1];
524
                //int j;
525

    
526
//                llRecordCount = ds.getRowCount();
527

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

    
537
                        return false;
538
                }
539
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
540
                featureQuery.setAttributeNames(new String[]{msFieldName});
541
                FeatureSet set = null;
542
                DisposableIterator iterator = null;
543
                try {
544
                        set = featureStore.getFeatureSet(featureQuery);
545
                        iterator = set.fastIterator();
546
                        while (iterator.hasNext()) {
547
                                Feature feature = (Feature) iterator.next();
548

    
549
                                // 'Nos cuidamos de recorrer todos los registros sin consultar
550
                                // la propiedad EOF del recordset
551
                                // for (i = 0; i < llRecordCount; i++) {
552
                                try {
553
                                        ldValor = feature.getDouble(0); 
554
                                        llRecordCount++;
555
                                } catch (Exception e) {
556
                                        // llRecordCount--;
557
                                        continue;
558
                                }
559
                                rdMediaTotal[0] = rdMediaTotal[0] + ldValor;
560

    
561
                                // 'Hay que insertar el valor en la posici�n adecuada. Para
562
                                // ello hacemos una b�squeda binaria
563
                                if (!mbObtenerPosicionEnVector(rVectorDatos, ldValor, llIndice,
564
                                                lbNuevoElemento)) {
565
                                        return false;
566
                                }
567

    
568
                                if (!lbNuevoElemento[0]) {
569
                                        if ((llIndice[0] < 0)
570
                                                        || (llIndice[0] > rVectorDatos.size())) {
571
                                                System.out.println("�ndice incorrecto!");
572

    
573
                                                return false;
574
                                        }
575

    
576
                                        ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Valor = ldValor; // 'Por
577
                                                                                                                                                                                // si
578
                                                                                                                                                                                // fuese
579
                                                                                                                                                                                // el
580
                                                                                                                                                                                // primer
581
                                                                                                                                                                                // elemento
582

    
583
                                        // 'Incrementamos el n� de coincidencias y damos el valor
584
                                        // por insertado
585
                                        ((udtDatosEstudio) rVectorDatos.get(llIndice[0])).Coincidencias = ((udtDatosEstudio) rVectorDatos
586
                                                        .get(llIndice[0])).Coincidencias +
587
                                        1;
588
                                } else {
589
                                        udtDatosEstudio udt = new udtDatosEstudio();
590
                                        udt.Valor = ldValor;
591
                                        udt.Coincidencias = 1;
592
                                        rVectorDatos.add(llIndice[0], udt);
593
                                }
594
                        }
595

    
596
                        rdMediaTotal[0] = rdMediaTotal[0] / llRecordCount;
597

    
598
                        return true;
599
                } finally {
600
                        if (iterator != null) {
601
                                iterator.dispose();
602
                        }
603
                        if (set != null) {
604
                                set.dispose();
605
                        }
606
                }
607
        }
608

    
609
        /**
610
         * Devuelve true si existe el campo en el registro.
611
         *
612
         * @param recordset Recordset.
613
         * @param msFieldName2 Nombre del campo.
614
         *
615
         * @return True si existe el campo.
616
         * @throws DataException TODO
617
         *
618
         */
619
        private boolean gbExisteCampoEnRegistro(FeatureStore fs,
620
                String msFieldName2) throws DataException  {
621
                if (((FeatureType)fs.getFeatureTypes().get(0)).getIndex(msFieldName2) == -1) {
622
                        return false;
623
                }
624

    
625
                return true;
626
        }
627

    
628
        /**
629
         * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
630
         * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
631
         * calcula todas! . En este caso no importa el valor de
632
         * vbDesplazAIzquierda
633
         *
634
         * @param rVectorDatos Datos
635
         * @param raClases Clases encontradas
636
         * @param rlaIndicesRuptura �ndices de ruptura
637
         * @param vdSDAM suma de la desviaci�n standard.
638
         * @param rdGVF Desviaci�n standard de los intervalos.
639
         * @param vlIndiceRupturaActual �ndice de ruptura actual.
640
         *
641
         * @return True si se ha calcula do correctamente.
642
         */
643
        /*private boolean mbCalcularGVF(ArrayList rVectorDatos,
644
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
645
                double[] rdGVF, int vlIndiceRupturaActual ) {
646
                return mbCalcularGVF(rVectorDatos, raClases, rlaIndicesRuptura, vdSDAM,
647
                        rdGVF, vlIndiceRupturaActual, true);
648
        }
649
*/
650
        /**
651
         * Esta funci�n s�lo calcula las SDCM de las clases adyacentes al �ndice de
652
         * ruptura actual. Si el �ndice de ruptura actual es -1 entonces las
653
         * calcula todas! . En este caso no importa el valor de
654
         * vbDesplazAIzquierda
655
         *
656
         * @param rVectorDatos Datos
657
         * @param raClases Calses que representan a los intervalos.
658
         * @param rlaIndicesRuptura �ndices de ruptura.
659
         * @param vdSDAM Desviaci�n standard.
660
         * @param rdGVF Desviaci�n standard de los intervalos.
661
         * @param vlIndiceRupturaActual �ndice de ruptura actual.
662
         * @param vbDesplazAIzquierda Desplazamiento a la izquierda.
663
         *
664
         * @return True si se ha calculado correctamente.
665
         */
666
        private boolean mbCalcularGVF(List<udtDatosEstudio> rVectorDatos,
667
                udtDatosClase[] raClases, int[] rlaIndicesRuptura, double vdSDAM,
668
                double[] rdGVF, int vlIndiceRupturaActual /* As Long = -1*/,
669
                boolean vbDesplazAIzquierda) {
670
                double ldSDCM_aux;
671

    
672
                int i;
673

    
674
                if (vlIndiceRupturaActual == -1) {
675
                        // 'Obtenemos los datos para todas las clases = intervalos
676
                        for (i = 0; i < rlaIndicesRuptura.length; i++) {
677
                                if (i == 0) { // LBound(rlaIndicesRuptura) Then
678

    
679
                                        if (!mbGetDatosClase(rVectorDatos, 0, rlaIndicesRuptura[i],
680
                                                                raClases, i)) {
681
                                                return false;
682
                                        }
683
                                } else {
684
                                        if (!mbGetDatosClase(rVectorDatos,
685
                                                                rlaIndicesRuptura[i - 1] + 1,
686
                                                                rlaIndicesRuptura[i], raClases, i)) {
687
                                                return false;
688
                                        }
689
                                }
690
                        }
691

    
692
                        //'Falta la �ltima clase
693
                        if (!mbGetDatosClase(rVectorDatos,
694
                                                rlaIndicesRuptura[rlaIndicesRuptura.length - 1] + 1,
695
                                                rVectorDatos.size() - 1, raClases, raClases.length - 1)) {
696
                                return false;
697
                        }
698
                } else {
699
                        i = vlIndiceRupturaActual;
700

    
701
                        //'Hay que determinar para qu� clases debemos volver a recalcular los datos en funci�n del �ndice de ruptura que estamos modificando
702
                        if (vbDesplazAIzquierda) {
703
                                //  'Recalcular los datos de la clase izquierda
704
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
705
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, false)) {
706
                                        return false;
707
                                }
708

    
709
                                //  'Recalcular los datos de la clase derecha
710
                                if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos,
711
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, true)) {
712
                                        return false;
713
                                }
714
                        } else {
715
                                //  'Recalcular los datos de la clase izquierda
716
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
717
                                                        rlaIndicesRuptura[i], vdSDAM, true)) {
718
                                        return false;
719
                                }
720

    
721
                                //  'Recalcular los datos de la clase derecha
722
                                if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos,
723
                                                        rlaIndicesRuptura[i], vdSDAM, false)) {
724
                                        return false;
725
                                }
726
                        }
727
                }
728

    
729
                ldSDCM_aux = 0;
730

    
731
                for (i = 0; i < raClases.length; i++) { //LBound(raClases) To UBound(raClases)
732
                        ldSDCM_aux = ldSDCM_aux + raClases[i].SDCM;
733
                }
734

    
735
                rdGVF[0] = (vdSDAM - ldSDCM_aux) / vdSDAM;
736
                //System.out.println(ldSDCM_aux);
737

    
738
                return true;
739
        }
740

    
741
        /**
742
         * Devuelve la "SDCM" de un conjunto de datos que vienen almacenados en el
743
         * vector rVectorDatos y que est�n delimitados por vlLimiteInf y
744
         * vlLimiteInf
745
         *
746
         * @param rVectorDatos Datos
747
         * @param vlLimiteInf L�mite inferior.
748
         * @param vlLimiteSup L�mite superior.
749
         * @param rClase Calses que representan a los intervalos.
750
         * @param numClas N�mero de calses.
751
         *
752
         * @return True si se ha calculado correctamente.
753
         */
754
        private boolean mbGetDatosClase(List<udtDatosEstudio> rVectorDatos,
755
                        int vlLimiteInf,
756
                int vlLimiteSup, udtDatosClase[] rClase, int numClas) {
757
                int i;
758

    
759
                if (vlLimiteInf < 0) {
760
                        return false;
761
                }
762

    
763
                if (vlLimiteSup > rVectorDatos.size()) {
764
                        return false;
765
                }
766

    
767
                if (vlLimiteSup < vlLimiteInf) {
768
                        return false;
769
                }
770

    
771
                // 'Inicializamos los datos de la clase
772
                rClase[numClas] = new udtDatosClase();
773

    
774
                //'Hallamos la media de la clase
775
                for (i = vlLimiteInf; i < (vlLimiteSup + 1); i++) {
776
                        rClase[numClas].NumElementos = rClase[numClas].NumElementos +
777
                                ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias;
778

    
779
                        //'rClase.Media = rClase.Media + (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
780
                        rClase[numClas].SumaTotal = rClase[numClas].SumaTotal +
781
                                (((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
782

    
783
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
784
                        rClase[numClas].SumaCuadradoTotal = rClase[numClas].SumaCuadradoTotal +
785
                                (Math.pow(((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(
786
                                                i)).Coincidencias, 2));
787
                }
788

    
789
                //'rClase.Media = rClase.Media / llTotalElementos
790
                rClase[numClas].Media = rClase[numClas].SumaTotal / rClase[numClas].NumElementos;
791
                rClase[numClas].SDCM = (rClase[numClas].SumaCuadradoTotal) -
792
                        (2 * rClase[numClas].Media * rClase[numClas].SumaTotal) +
793
                        (rClase[numClas].NumElementos * Math.pow(rClase[numClas].Media, 2));
794
                /*if (new Double(rClase[numClas].SDCM).isNaN()){
795
                        System.out.println(rClase[numClas].SDCM);
796
                }*/
797
                return true;
798
        }
799

    
800
        /**
801
         * Recalcula los datos de las clases.
802
         *
803
         * @param rClase Clases.
804
         * @param i �adir �adir �adir �adir indica si a la clase se le a�ade un
805
         *                   elemento (True) o se le quita (False)
806
         * @param rVectorDatos Datos.
807
         * @param vlIndiceElemento es el �ndice del elemento que se le va a�adir o
808
         *                   a quitar a la clase
809
         * @param vdSDAM desviaci�n standard.
810
         * @param vbA �adir DOCUMENT ME!
811
         *
812
         * @return True si se ha calculado correctamente.
813
         */
814
        private boolean mbRecalcularDatosClase(udtDatosClase[] rClase, int i,
815
                        List<udtDatosEstudio> rVectorDatos, int vlIndiceElemento,
816
                        double vdSDAM,
817
                boolean vbAnyadir) {
818
                double ldValor;
819
                long llNumCoincidencias;
820
try{
821
        if (vlIndiceElemento>rVectorDatos.size()-1) {
822
                return true;
823
        }
824
                ldValor = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Valor;
825
                llNumCoincidencias = ((udtDatosEstudio) rVectorDatos.get(vlIndiceElemento)).Coincidencias;
826

    
827
                if (vbAnyadir) {
828
                        //'Actualizamos la suma total
829
                        rClase[i].SumaTotal = rClase[i].SumaTotal +
830
                                (ldValor * llNumCoincidencias);
831

    
832
                        //'Actualizamos la suma de cuadrados total
833
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal +
834
                                (Math.pow((ldValor * llNumCoincidencias), 2));
835

    
836
                        //'Actualizamos el producto total
837
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (ldValor * llNumCoincidencias)
838
                        //'Actualizamos el n� de elementos
839
                        rClase[i].NumElementos = rClase[i].NumElementos +
840
                                llNumCoincidencias;
841
                } else {
842
                        //'Actualizamos la suma total
843
                        rClase[i].SumaTotal = rClase[i].SumaTotal -
844
                                (ldValor * llNumCoincidencias);
845

    
846
                        // 'Actualizamos la suma de cuadrados total
847
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal -
848
                                (Math.pow((ldValor * llNumCoincidencias), 2));
849

    
850
                        // 'Actualizamos el producto total
851
                        // 'rClase.ProductoTotal = rClase.ProductoTotal / (ldValor * llNumCoincidencias)
852
                        // 'Actualizamos el n� de elementos
853
                        rClase[i].NumElementos = rClase[i].NumElementos -
854
                                llNumCoincidencias;
855
                } // 'If vbA�adir Then
856
                if (rClase[i].NumElementos<=0) {
857
                        rClase[i].NumElementos=1;
858
                }
859
                //'Obtenemos la nueva media
860
                rClase[i].Media = rClase[i].SumaTotal / rClase[i].NumElementos;
861

    
862
                //'Actualizamos la SDCM
863
                rClase[i].SDCM = (rClase[i].SumaCuadradoTotal) -
864
                        (2 * rClase[i].Media * rClase[i].SumaTotal) +
865
                        (rClase[i].NumElementos * Math.pow(rClase[i].Media, 2));
866

    
867
}catch (Exception e) {
868
        return false;
869
}
870
                return true;
871
        }
872

    
873
        /**
874
         * Devuelve el valor de ruptura seg�n el �ndice que se le pasa como
875
         * par�metro.
876
         *
877
         * @param viIndice �nidice del valor de ruptura.
878
         *
879
         * @return Valor de ruptura.
880
         */
881
        public double getValorRuptura(int viIndice) {
882
                return mdaValoresRuptura[viIndice];
883
        }
884

    
885
        /**
886
         * Devuelve el valor inicial de cada intervalo
887
         *
888
         * @param index �ndice del intervalo
889
         *
890
         * @return valor del intervalo.
891
         */
892
        public double getValInit(int index) {
893
                return mdaValInit[index];
894
        }
895

    
896
        /**
897
         * Devuelve el n�mero de intervalos que se pueden representar, no tiene
898
         * porque coincidir con el n�mero de intervalos que se piden.
899
         *
900
         * @return N�mero de intervalos calculados.
901
         */
902
        public int getNumIntervals() {
903
                return miNumIntervalosGenerados;
904
        }
905

    
906
        /**
907
         * Clase para contener los atributos Valor y coincidencias.
908
         *
909
         * @author Vicente Caballero Navarro
910
         */
911
        private class udtDatosEstudio {
912
                private double Valor; //
913
                private long Coincidencias;
914
        }
915

    
916
        /**
917
         * Clase para contener los atributos: N�mero de Elementos. Media.
918
         * SumaTotal. SumaCuadradoTotal. Desviaci�n standard.
919
         *
920
         * @author Vicente Caballero Navarro
921
         */
922
        private class udtDatosClase {
923
                private long NumElementos; //             'N� total de elementos que hay en la clase
924
                private double Media; //                 'Media de la clase
925
                private double SumaTotal; //              'Suma total de los elementos
926

    
927
                //'ProductoTotal          'Producto total de los elementos '�dar� problemas de desbordamiento?
928
                private double SumaCuadradoTotal; //      'Suma del total de los cuadrados de los elementos
929
                private double SDCM; //                  'Suma de la desviaci�n t�pica de los elementos de la clase respecto de la media de la clase
930
        }
931
}