Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / legend / impl / NaturalIntervalGenerator.java @ 40560

History | View | Annotate | Download (30.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl;
25

    
26
import java.util.ArrayList;
27
import java.util.List;
28

    
29
import org.slf4j.Logger;
30
import org.slf4j.LoggerFactory;
31

    
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.tools.dispose.DisposableIterator;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureQuery;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39

    
40
/**
41
 * Calcula los intervalos naturales.
42
 *
43
 * @author Vicente Caballero Navarro
44
 */
45
public class NaturalIntervalGenerator {
46

    
47
    private static final Logger logger =
48
        LoggerFactory.getLogger(NaturalIntervalGenerator.class);
49
    
50
        private String msFieldName;
51
        private int miNumIntervalosSolicitados;
52
        private int miNumIntervalosGenerados;
53
        private double[] mdaValoresRuptura;
54
        private double[] mdaValInit;
55
        private FeatureStore featureStore;
56

    
57
        /**
58
         * Crea un nuevo IntervalGenerator.
59
         *
60
         * @param layer AlphanumericData
61
         * @param field Nombre del campo.
62
         * @param numIntervals N�mero de intervalos.
63
         */
64
        public NaturalIntervalGenerator(FeatureStore fs, String field,
65
                int numIntervals) {
66
                featureStore = fs;
67
                msFieldName = field;
68
                miNumIntervalosSolicitados = numIntervals;
69
        }
70

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

    
96
                double ldValorComparacion;
97

    
98
                rbNuevoElemento[0] = false;
99
                rlIndiceCorrespondiente[0] = -1;
100

    
101
                //'Si el vector estiviese vac�o... (tuviese un s�lo elemento y el n�mero de coincidencias fuese 0)
102
                if (rVectorDatos.size() == 1) {
103
                        if (((udtDatosEstudio) rVectorDatos.get(0)).Coincidencias == 0) {
104
                                rlIndiceCorrespondiente[0] = 0;
105
                                rbNuevoElemento[0] = false; //'No tenemos que a�adir un nuevo elemento al vector
106

    
107
                                return true;
108
                        }
109
                }
110

    
111
                llIndiceIzq = 0;
112
                llIndiceDer = rVectorDatos.size() - 1;
113
                llMedio = (llIndiceIzq + llIndiceDer) / 2; //'Divisi�n entera!
114

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

    
119
                        //'Si el valor a insertar es mayor que el valor de comparaci�n...
120
                        if (vdValorAInsertar > ldValorComparacion) {
121
                                //      'La zona de b�squeda queda restringida a la parte de la derecha
122
                                llIndiceIzq = llMedio + 1;
123
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
124

    
125
                                //    'Si el valor a insertar es menor que el valor de comparaci�n...
126
                        } else if (vdValorAInsertar < ldValorComparacion) {
127
                                //          'La zona de b�squeda queda restringida a la parte de la derecha
128
                                llIndiceDer = llMedio - 1;
129
                                llMedio = (llIndiceIzq + llIndiceDer) / 2;
130

    
131
                                //        'Si el valor de comparaci�n coincide con el valor a insertar
132
                        } else if (vdValorAInsertar == ldValorComparacion) {
133
                                rlIndiceCorrespondiente[0] = llMedio;
134
                                rbNuevoElemento[0] = false;
135

    
136
                                return true;
137
                        }
138
                }
139

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

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

    
153
                if (vdValorAInsertar > ldValorComparacion) {
154
                        rlIndiceCorrespondiente[0] = llMedio + 1;
155
                } else {
156
                        rlIndiceCorrespondiente[0] = llMedio;
157
                }
158

    
159
                return true;
160
        }
161

    
162
        /**
163
         * M�todo para generar los intervalos.
164
         *
165
         * @return true si se han generado correctamente.
166
         * @throws DataException TODO
167
         */
168
        public boolean generarIntervalos()
169
                throws DataException {
170
                List<udtDatosEstudio> lVectorDatos;
171
                double[] ldMediaTotal = new double[1];
172
                double[] ldSDAM = new double[1];
173

    
174
                int[] llaIndicesRupturas;
175

    
176
                double[] ldUltimaGVF = new double[1];
177
                double[] ldNuevaGVF = new double[1];
178

    
179
                int i;
180
                int liNumClasesReales;
181
                int llNumElementosPorClase;
182

    
183
                //    'Obtener los datos a estudiar ordenados ascendentemente y obtener la media total
184
                //ReDim lVectorDatos(0)
185
                lVectorDatos = new ArrayList<udtDatosEstudio>();
186

    
187
                lVectorDatos.add(new udtDatosEstudio());
188

    
189
                if (!mbObtenerDatos(lVectorDatos, ldMediaTotal)) {
190
                        return false; //SalidaSinMensaje
191
                }
192

    
193
                logger.info("Analizando datos en generarIntervalos() ...");
194

    
195
                /// Call gEstablecerDescripcionProceso("Analizando datos ...", False)
196
                //  'Calcular la suma de las desviaciones t�picas del total de los datos respecto de la media total
197
                ldSDAM[0] = mbGetSumSquaredDeviationArrayMean(lVectorDatos,
198
                                ldMediaTotal[0]);
199

    
200
                ///if (lVectorDatos.length==0){
201
                if (lVectorDatos.isEmpty()) {
202
                        //      'S�lo se pueden generar dos intervalos -> hay un valor de ruptura
203
                        ///ReDim mdaValoresRuptura(0)
204
                        mdaValoresRuptura[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
205
                        mdaValInit[0] = ((udtDatosEstudio) lVectorDatos.get(0)).Valor;
206
                        miNumIntervalosGenerados = 2;
207

    
208
                        return true;
209
                }
210

    
211
                //  'Calculamos el n�mero m�ximo de clases reales que podemos generar.
212
                //  'Este n�mero ser�a igual al n� de elementos que tenga el vector de datos.
213
                if (miNumIntervalosSolicitados > (lVectorDatos.size())) {
214
                        liNumClasesReales = lVectorDatos.size() + 1;
215
                } else {
216
                        liNumClasesReales = miNumIntervalosSolicitados;
217
                }
218

    
219
                //  'Establecemos las clases iniciales especificando unos �ndices de ruptura en ppo. equidistantes
220
                llaIndicesRupturas = new int[liNumClasesReales - 1];
221
                llNumElementosPorClase = (lVectorDatos.size()) / liNumClasesReales;
222

    
223
                for (i = 0; i < llaIndicesRupturas.length; i++) {
224
                        if (i == 0) {
225
                                llaIndicesRupturas[i] = llNumElementosPorClase - 1;
226
                        } else {
227
                                llaIndicesRupturas[i] = llaIndicesRupturas[i - 1] +
228
                                        llNumElementosPorClase;
229
                        }
230
                }
231

    
232
                udtDatosClase[] ldaSDCM_Parciales = new udtDatosClase[llaIndicesRupturas.length +
233
                        1];
234
                udtDatosClase[] ldaSDCM_Validos = new udtDatosClase[llaIndicesRupturas.length +
235
                        1];
236

    
237
                ///ReDim ldaSDCM_Parciales(UBound(llaIndicesRupturas()) + 1)
238
                ///ReDim ldaSDCM_Validos(UBound(ldaSDCM_Parciales()) + 1)
239
                if (llaIndicesRupturas.length == 0) {
240
                        return true;
241
                }
242

    
243
                //  'Calcular la bondad inicial
244
                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales, llaIndicesRupturas,
245
                                        ldSDAM[0], ldUltimaGVF, -1, false)) {
246
//                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"el_numero_maximo_de_intervalos_para_este_campo_es")+": "+lVectorDatos.size());
247
                        miNumIntervalosSolicitados=lVectorDatos.size();
248
                        generarIntervalos();
249
                        return false;
250
                }
251

    
252
                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
253

    
254
                boolean lbMoverADerecha;
255
                boolean lbMoverAIzquierda;
256
                boolean lbIntentarDesplazamiento;
257
                int llIndiceRupturaOriginal;
258

    
259
                long k;
260
                double ldGVFentrepasadas;
261

    
262
                ldGVFentrepasadas = ldUltimaGVF[0];
263

    
264
                //'liNumClasesReales no ser� muy grande (11 es el m�ximo)
265
                for (k = 1; k <= 100; k++) {
266
                        //      'Para cada �ndice de ruptura...
267
                        for (i = 0; i < (llaIndicesRupturas.length); i++) {
268
                                lbMoverADerecha = false;
269
                                lbMoverAIzquierda = false;
270
                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
271
                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
272

    
273
                                //'Hay que decidir hacia donde hay que desplazar el �ndice de ruptura
274
                                //'Probamos moviendo a derecha (si se puede)
275
                                lbIntentarDesplazamiento = false;
276

    
277
                                if (i == (llaIndicesRupturas.length - 1)) {
278
                                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
279
                                                lbIntentarDesplazamiento = true;
280
                                        }
281
                                } else {
282
                                        if ((llaIndicesRupturas[i] + 1) < llaIndicesRupturas[i + 1]) {
283
                                                lbIntentarDesplazamiento = true;
284
                                        } //'If (llaIndicesRupturas(i) + 1) < llaIndicesRupturas(i + 1) Then
285
                                } //'If i = UBound(llaIndicesRupturas) Then
286

    
287
                                if (lbIntentarDesplazamiento) {
288
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
289

    
290
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
291
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
292
                                                                false)) {
293
                                                return false;
294
                                        }
295

    
296
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
297
                                                lbMoverADerecha = true;
298
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
299
                                        } else {
300
                                                //'Dejamos el �ndice de ruputura como estaba y probamos con un desplazamiento a izquierda
301
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
302
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
303
                                        }
304
                                } //'If lbIntentarDesplazamiento Then
305

    
306
                                lbIntentarDesplazamiento = false;
307

    
308
                                //'Probamos moviendo a izquierda (si se puede y no estamos moviendo ya a derechas)
309
                                if (!lbMoverADerecha) {
310
                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
311

    
312
                                                if ((llaIndicesRupturas[i] - 1) >= 0) { //LBound(lVectorDatos()) Then
313
                                                        lbIntentarDesplazamiento = true;
314
                                                } //'If (llaIndicesRupturas(i) - 1) >= LBound(lVectorDatos()) Then
315
                                        } else {
316
                                                if ((llaIndicesRupturas[i] - 1) > llaIndicesRupturas[i -
317
                                                                1]) {
318
                                                        lbIntentarDesplazamiento = true;
319
                                                } //'If (llaIndicesRupturas(i) - 1) > llaIndicesRupturas(i - 1) Then
320
                                        } //'If i = LBound(llaIndicesRupturas) Then
321
                                } //'If Not lbMoverADerecha Then
322

    
323
                                if (lbIntentarDesplazamiento) {
324
                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1;
325

    
326
                                        if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
327
                                                                llaIndicesRupturas, ldSDAM[0], ldNuevaGVF, i,
328
                                                                true)) {
329
                                                return false;
330
                                        }
331

    
332
                                        if (ldNuevaGVF[0] > ldUltimaGVF[0]) {
333
                                                lbMoverAIzquierda = true;
334
                                                ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
335
                                        } else {
336
                                                //'Dejamos el �ndice de ruputura como estaba
337
                                                llaIndicesRupturas[i] = llIndiceRupturaOriginal;
338
                                                ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
339
                                        }
340
                                } //'If lbIntentarDesplazamiento Then
341

    
342
                                lbIntentarDesplazamiento = false;
343

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

    
348
                                        boolean exit = false;
349

    
350
                                        while (!exit) {
351
                                                llIndiceRupturaOriginal = llaIndicesRupturas[i];
352

    
353
                                                if (lbMoverADerecha) {
354
                                                        if (i == (llaIndicesRupturas.length - 1)) {
355
                                                                if ((llaIndicesRupturas[i] + 1) >= lVectorDatos.size()) {
356
                                                                        exit = true;
357
                                                                }
358
                                                        } else {
359
                                                                if ((llaIndicesRupturas[i] + 1) >= llaIndicesRupturas[i +
360
                                                                                1]) {
361
                                                                        exit = true;
362
                                                                }
363
                                                        } //'If i = UBound(llaIndicesRupturas) Then
364

    
365
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] + 1;
366
                                                } else { //'If lbMoverAIzquierda Then
367

    
368
                                                        if (i == 0) { //LBound(llaIndicesRupturas) Then
369

    
370
                                                                if ((llaIndicesRupturas[i] - 1) < 0) { //LBound(lVectorDatos()) Then Exit Do
371
                                                                        exit = true;
372
                                                                }
373
                                                        } else {
374
                                                                if ((llaIndicesRupturas[i] - 1) <= llaIndicesRupturas[i -
375
                                                                                1]) {
376
                                                                        exit = true;
377
                                                                }
378
                                                        } //'If i = LBound(llaIndicesRupturas) Then
379

    
380
                                                        llaIndicesRupturas[i] = llaIndicesRupturas[i] - 1; //////////////////
381
                                                } //'If lbMoverADerecha Then
382

    
383
                                                if (!mbCalcularGVF(lVectorDatos, ldaSDCM_Parciales,
384
                                                                        llaIndicesRupturas, ldSDAM[0], ldNuevaGVF,
385
                                                                        i, lbMoverAIzquierda)) {
386
                                                        return false;
387
                                                }
388

    
389
                                                if (ldNuevaGVF[0] < ldUltimaGVF[0]) {
390
                                                        // 'Dejar el �ndice donde estaba
391
                                                        llaIndicesRupturas[i] = llIndiceRupturaOriginal;
392
                                                        ldaSDCM_Parciales = getArray(ldaSDCM_Validos);
393
                                                        exit = true;
394
                                                } else {
395
                                                        ldUltimaGVF[0] = ldNuevaGVF[0];
396
                                                        ldaSDCM_Validos = getArray(ldaSDCM_Parciales);
397
                                                }
398
                                        }
399
                                } //'If lbMoverAIzquierda Or lbMoverADerecha Then
400
                        }
401

    
402
                        if (ldUltimaGVF[0] <= ldGVFentrepasadas) {
403
                                i = 101;
404
                        }
405

    
406
                        ldGVFentrepasadas = ldUltimaGVF[0];
407
                }
408

    
409
                //   'A partir de aqu� ya no se puede cancelar nada
410
                mdaValoresRuptura = new double[llaIndicesRupturas.length];
411
                mdaValInit = new double[llaIndicesRupturas.length];
412

    
413
                for (i = 0; i < mdaValoresRuptura.length; i++) { // LBound(mdaValoresRuptura) To UBound(mdaValoresRuptura)
414
                        if (llaIndicesRupturas[i]==-1) {
415
                                llaIndicesRupturas[i]=1;
416
                        }
417
                        if (llaIndicesRupturas[i]>lVectorDatos.size()-1) {
418
                                llaIndicesRupturas[i]=lVectorDatos.size()-1;
419
                        }
420
                        mdaValoresRuptura[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
421

    
422
                        if ((llaIndicesRupturas[i] + 1) < lVectorDatos.size()) {
423
                                mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i] +
424
                                                1)).Valor;
425
                        } else {
426
                                mdaValInit[i] = ((udtDatosEstudio) lVectorDatos.get(llaIndicesRupturas[i])).Valor;
427
                        }
428

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

    
435
                miNumIntervalosGenerados = mdaValoresRuptura.length + 2;
436

    
437
                ldaSDCM_Validos = null;
438
                ldaSDCM_Parciales = null;
439
                lVectorDatos = null;
440

    
441
                return true;
442
        }
443

    
444
        /**
445
         * DOCUMENT ME!
446
         *
447
         * @param array DOCUMENT ME!
448
         *
449
         * @return DOCUMENT ME!
450
         */
451
        private udtDatosClase[] getArray(udtDatosClase[] array) {
452
                udtDatosClase[] aux = new udtDatosClase[array.length];
453

    
454
                for (int i = 0; i < array.length; i++) {
455
                        aux[i] = new udtDatosClase();
456
                        aux[i].Media = array[i].Media;
457
                        aux[i].NumElementos = array[i].NumElementos;
458
                        aux[i].SDCM = array[i].SDCM;
459
                        aux[i].SumaCuadradoTotal = array[i].SumaCuadradoTotal;
460
                        aux[i].SumaTotal = array[i].SumaTotal;
461
                }
462

    
463
                return aux;
464
        }
465

    
466
        /**
467
         * Devuelve la "SDAM" de un conjunto de datos que vienen almacenados en el
468
         * vector rVectorDatos
469
         *
470
         * @param rVectorDatos Datos
471
         * @param vdMedia Media
472
         *
473
         * @return suma de las desviaciones t�picas del total de los datos respecto
474
         *                    de la media total
475
         */
476
        private double mbGetSumSquaredDeviationArrayMean(
477
                        List<udtDatosEstudio> rVectorDatos,
478
                double vdMedia) {
479
                int i;
480

    
481
                double rdSDAM = 0;
482

    
483
                for (i = 0; i < rVectorDatos.size(); i++) { // LBound(rVectorDatos) To UBound(rVectorDatos)
484
                        rdSDAM = rdSDAM +
485
                                (Math.pow((((udtDatosEstudio) rVectorDatos.get(i)).Valor -
486
                                        vdMedia), 2) * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
487
                }
488

    
489
                return rdSDAM;
490
        }
491

    
492
        /**
493
         * Esta funci�n obtiene los datos en los que queremos hallar las rupturas
494
         * naturales. Los datos se devuelven ordenados en un vector. Tambi�n
495
         * devuelve la media total
496
         *
497
         * @param rVectorDatos Datos
498
         * @param rdMediaTotal Media total
499
         *
500
         * @return True si se ha calculado correctamente.
501
         * @throws DataException TODO
502
         */
503
        private boolean mbObtenerDatos(List<udtDatosEstudio> rVectorDatos,
504
                        double[] rdMediaTotal)
505
                throws DataException {
506
                double ldValor;
507

    
508
//                int i;
509
                long llRecordCount=0;
510

    
511
                int[] llIndice = new int[1];
512
                boolean[] lbNuevoElemento = new boolean[1];
513
                //int j;
514

    
515
//                llRecordCount = ds.getRowCount();
516

    
517
                if (!gbExisteCampoEnRegistro(featureStore, msFieldName)) {
518
                        if (msFieldName == "") {
519
                                System.out.println(
520
                                        "No se ha establecido el nombre del campo origen!");
521
                        } else {
522
                                System.out.println("El campo '" + msFieldName +
523
                                        "' no pertence a la capa!");
524
                        }
525

    
526
                        return false;
527
                }
528
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
529
                featureQuery.setAttributeNames(new String[]{msFieldName});
530
                FeatureSet set = null;
531
                DisposableIterator iterator = null;
532
                try {
533
                        set = featureStore.getFeatureSet(featureQuery);
534
                        iterator = set.fastIterator();
535
                        while (iterator.hasNext()) {
536
                                Feature feature = (Feature) iterator.next();
537

    
538
                                // 'Nos cuidamos de recorrer todos los registros sin consultar
539
                                // la propiedad EOF del recordset
540
                                // for (i = 0; i < llRecordCount; i++) {
541
                                try {
542
                                        ldValor = feature.getDouble(0); 
543
                                        llRecordCount++;
544
                                } catch (Exception e) {
545
                                        // llRecordCount--;
546
                                        continue;
547
                                }
548
                                rdMediaTotal[0] = rdMediaTotal[0] + ldValor;
549

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

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

    
562
                                                return false;
563
                                        }
564

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

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

    
585
                        rdMediaTotal[0] = rdMediaTotal[0] / llRecordCount;
586

    
587
                        return true;
588
                } finally {
589
                        if (iterator != null) {
590
                                iterator.dispose();
591
                        }
592
                        if (set != null) {
593
                                set.dispose();
594
                        }
595
                }
596
        }
597

    
598
        /**
599
         * Devuelve true si existe el campo en el registro.
600
         *
601
         * @param recordset Recordset.
602
         * @param msFieldName2 Nombre del campo.
603
         *
604
         * @return True si existe el campo.
605
         * @throws DataException TODO
606
         *
607
         */
608
        private boolean gbExisteCampoEnRegistro(FeatureStore fs,
609
                String msFieldName2) throws DataException  {
610
                if (((FeatureType)fs.getFeatureTypes().get(0)).getIndex(msFieldName2) == -1) {
611
                        return false;
612
                }
613

    
614
                return true;
615
        }
616

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

    
661
                int i;
662

    
663
                if (vlIndiceRupturaActual == -1) {
664
                        // 'Obtenemos los datos para todas las clases = intervalos
665
                        for (i = 0; i < rlaIndicesRuptura.length; i++) {
666
                                if (i == 0) { // LBound(rlaIndicesRuptura) Then
667

    
668
                                        if (!mbGetDatosClase(rVectorDatos, 0, rlaIndicesRuptura[i],
669
                                                                raClases, i)) {
670
                                                return false;
671
                                        }
672
                                } else {
673
                                        if (!mbGetDatosClase(rVectorDatos,
674
                                                                rlaIndicesRuptura[i - 1] + 1,
675
                                                                rlaIndicesRuptura[i], raClases, i)) {
676
                                                return false;
677
                                        }
678
                                }
679
                        }
680

    
681
                        //'Falta la �ltima clase
682
                        if (!mbGetDatosClase(rVectorDatos,
683
                                                rlaIndicesRuptura[rlaIndicesRuptura.length - 1] + 1,
684
                                                rVectorDatos.size() - 1, raClases, raClases.length - 1)) {
685
                                return false;
686
                        }
687
                } else {
688
                        i = vlIndiceRupturaActual;
689

    
690
                        //'Hay que determinar para qu� clases debemos volver a recalcular los datos en funci�n del �ndice de ruptura que estamos modificando
691
                        if (vbDesplazAIzquierda) {
692
                                //  'Recalcular los datos de la clase izquierda
693
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
694
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, false)) {
695
                                        return false;
696
                                }
697

    
698
                                //  'Recalcular los datos de la clase derecha
699
                                if (!mbRecalcularDatosClase(raClases, i + 1, rVectorDatos,
700
                                                        rlaIndicesRuptura[i] + 1, vdSDAM, true)) {
701
                                        return false;
702
                                }
703
                        } else {
704
                                //  'Recalcular los datos de la clase izquierda
705
                                if (!mbRecalcularDatosClase(raClases, i, rVectorDatos,
706
                                                        rlaIndicesRuptura[i], vdSDAM, true)) {
707
                                        return false;
708
                                }
709

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

    
718
                ldSDCM_aux = 0;
719

    
720
                for (i = 0; i < raClases.length; i++) { //LBound(raClases) To UBound(raClases)
721
                        ldSDCM_aux = ldSDCM_aux + raClases[i].SDCM;
722
                }
723

    
724
                rdGVF[0] = (vdSDAM - ldSDCM_aux) / vdSDAM;
725
                //System.out.println(ldSDCM_aux);
726

    
727
                return true;
728
        }
729

    
730
        /**
731
         * Devuelve la "SDCM" de un conjunto de datos que vienen almacenados en el
732
         * vector rVectorDatos y que est�n delimitados por vlLimiteInf y
733
         * vlLimiteInf
734
         *
735
         * @param rVectorDatos Datos
736
         * @param vlLimiteInf L�mite inferior.
737
         * @param vlLimiteSup L�mite superior.
738
         * @param rClase Calses que representan a los intervalos.
739
         * @param numClas N�mero de calses.
740
         *
741
         * @return True si se ha calculado correctamente.
742
         */
743
        private boolean mbGetDatosClase(List<udtDatosEstudio> rVectorDatos,
744
                        int vlLimiteInf,
745
                int vlLimiteSup, udtDatosClase[] rClase, int numClas) {
746
                int i;
747

    
748
                if (vlLimiteInf < 0) {
749
                        return false;
750
                }
751

    
752
                if (vlLimiteSup > rVectorDatos.size()) {
753
                        return false;
754
                }
755

    
756
                if (vlLimiteSup < vlLimiteInf) {
757
                        return false;
758
                }
759

    
760
                // 'Inicializamos los datos de la clase
761
                rClase[numClas] = new udtDatosClase();
762

    
763
                //'Hallamos la media de la clase
764
                for (i = vlLimiteInf; i < (vlLimiteSup + 1); i++) {
765
                        rClase[numClas].NumElementos = rClase[numClas].NumElementos +
766
                                ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias;
767

    
768
                        //'rClase.Media = rClase.Media + (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
769
                        rClase[numClas].SumaTotal = rClase[numClas].SumaTotal +
770
                                (((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(i)).Coincidencias);
771

    
772
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (rVectorDatos(i).Valor * rVectorDatos(i).Coincidencias)
773
                        rClase[numClas].SumaCuadradoTotal = rClase[numClas].SumaCuadradoTotal +
774
                                (Math.pow(((udtDatosEstudio) rVectorDatos.get(i)).Valor * ((udtDatosEstudio) rVectorDatos.get(
775
                                                i)).Coincidencias, 2));
776
                }
777

    
778
                //'rClase.Media = rClase.Media / llTotalElementos
779
                rClase[numClas].Media = rClase[numClas].SumaTotal / rClase[numClas].NumElementos;
780
                rClase[numClas].SDCM = (rClase[numClas].SumaCuadradoTotal) -
781
                        (2 * rClase[numClas].Media * rClase[numClas].SumaTotal) +
782
                        (rClase[numClas].NumElementos * Math.pow(rClase[numClas].Media, 2));
783
                /*if (new Double(rClase[numClas].SDCM).isNaN()){
784
                        System.out.println(rClase[numClas].SDCM);
785
                }*/
786
                return true;
787
        }
788

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

    
816
                if (vbAnyadir) {
817
                        //'Actualizamos la suma total
818
                        rClase[i].SumaTotal = rClase[i].SumaTotal +
819
                                (ldValor * llNumCoincidencias);
820

    
821
                        //'Actualizamos la suma de cuadrados total
822
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal +
823
                                (Math.pow((ldValor * llNumCoincidencias), 2));
824

    
825
                        //'Actualizamos el producto total
826
                        //'rClase.ProductoTotal = rClase.ProductoTotal * (ldValor * llNumCoincidencias)
827
                        //'Actualizamos el n� de elementos
828
                        rClase[i].NumElementos = rClase[i].NumElementos +
829
                                llNumCoincidencias;
830
                } else {
831
                        //'Actualizamos la suma total
832
                        rClase[i].SumaTotal = rClase[i].SumaTotal -
833
                                (ldValor * llNumCoincidencias);
834

    
835
                        // 'Actualizamos la suma de cuadrados total
836
                        rClase[i].SumaCuadradoTotal = rClase[i].SumaCuadradoTotal -
837
                                (Math.pow((ldValor * llNumCoincidencias), 2));
838

    
839
                        // 'Actualizamos el producto total
840
                        // 'rClase.ProductoTotal = rClase.ProductoTotal / (ldValor * llNumCoincidencias)
841
                        // 'Actualizamos el n� de elementos
842
                        rClase[i].NumElementos = rClase[i].NumElementos -
843
                                llNumCoincidencias;
844
                } // 'If vbA�adir Then
845
                if (rClase[i].NumElementos<=0) {
846
                        rClase[i].NumElementos=1;
847
                }
848
                //'Obtenemos la nueva media
849
                rClase[i].Media = rClase[i].SumaTotal / rClase[i].NumElementos;
850

    
851
                //'Actualizamos la SDCM
852
                rClase[i].SDCM = (rClase[i].SumaCuadradoTotal) -
853
                        (2 * rClase[i].Media * rClase[i].SumaTotal) +
854
                        (rClase[i].NumElementos * Math.pow(rClase[i].Media, 2));
855

    
856
}catch (Exception e) {
857
        return false;
858
}
859
                return true;
860
        }
861

    
862
        /**
863
         * Devuelve el valor de ruptura seg�n el �ndice que se le pasa como
864
         * par�metro.
865
         *
866
         * @param viIndice �nidice del valor de ruptura.
867
         *
868
         * @return Valor de ruptura.
869
         */
870
        public double getValorRuptura(int viIndice) {
871
                return mdaValoresRuptura[viIndice];
872
        }
873

    
874
        /**
875
         * Devuelve el valor inicial de cada intervalo
876
         *
877
         * @param index �ndice del intervalo
878
         *
879
         * @return valor del intervalo.
880
         */
881
        public double getValInit(int index) {
882
                return mdaValInit[index];
883
        }
884

    
885
        /**
886
         * Devuelve el n�mero de intervalos que se pueden representar, no tiene
887
         * porque coincidir con el n�mero de intervalos que se piden.
888
         *
889
         * @return N�mero de intervalos calculados.
890
         */
891
        public int getNumIntervals() {
892
                return miNumIntervalosGenerados;
893
        }
894

    
895
        /**
896
         * Clase para contener los atributos Valor y coincidencias.
897
         *
898
         * @author Vicente Caballero Navarro
899
         */
900
        private class udtDatosEstudio {
901
                private double Valor; //
902
                private long Coincidencias;
903
        }
904

    
905
        /**
906
         * Clase para contener los atributos: N�mero de Elementos. Media.
907
         * SumaTotal. SumaCuadradoTotal. Desviaci�n standard.
908
         *
909
         * @author Vicente Caballero Navarro
910
         */
911
        private class udtDatosClase {
912
                private long NumElementos; //             'N� total de elementos que hay en la clase
913
                private double Media; //                 'Media de la clase
914
                private double SumaTotal; //              'Suma total de los elementos
915

    
916
                //'ProductoTotal          'Producto total de los elementos '�dar� problemas de desbordamiento?
917
                private double SumaCuadradoTotal; //      'Suma del total de los cuadrados de los elementos
918
                private double SDCM; //                  'Suma de la desviaci�n t�pica de los elementos de la clase respecto de la media de la clase
919
        }
920
}