Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / store / properties / SimpleProviderStatistics.java @ 1419

History | View | Annotate | Download (19 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22
package org.gvsig.raster.impl.store.properties;
23

    
24
import java.util.ArrayList;
25

    
26
import org.gvsig.fmap.dal.coverage.RasterLibrary;
27
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
29
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
30
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
31
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
32
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
33
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
34
import org.gvsig.raster.impl.process.RasterTask;
35
import org.gvsig.raster.impl.process.RasterTaskQueue;
36
import org.gvsig.raster.impl.provider.RasterProvider;
37
/**
38
 * Statistics for a raster provider.
39
 *  
40
 * @author Nacho Brodin (nachobrodin@gmail.com)
41
 */
42
public class SimpleProviderStatistics extends AbstractStatistics {
43
        protected RasterProvider    provider                = null;
44
        protected int               percent                 = 0;
45
        protected boolean           forceToRecalc           = false;
46
        
47
        /**
48
         * Constructor. Asigna el fichero asociado.
49
         */
50
        public SimpleProviderStatistics(RasterProvider prov) {
51
                this.provider = prov;
52
                if(provider != null)
53
                        bandCount = provider.getBandCount();
54
        }
55
        
56
        /**
57
         * Obtiene el dataset asociado
58
         * @return
59
         */
60
        public RasterProvider getDataProvider() {
61
                return provider;
62
        }
63
        
64
        /**
65
         * Asigna el valor m?ximo del grid
66
         * @return Valor m?ximo
67
         */
68
        public void setMax(double[] max) {
69
                this.max = max;
70
        }
71

    
72
        /**
73
         * Asigna el valor del segundo m?ximo
74
         * @return Valor del segundo m?ximo
75
         */
76
        public void setSecondMax(double[] smax) {
77
                this.secondMax = smax;
78
        }
79
        
80
        /**
81
         * Asigna el valor m?ximo del grid
82
         * @return Valor m?ximo
83
         */
84
        public void setMaxRGB(double[] max) {
85
                this.maxByteUnsigned = max;
86
        }
87

    
88
        /**
89
         * Asigna el valor del segundo m?ximo
90
         * @return Valor del segundo m?ximo
91
         */
92
        public void setSecondMaxRGB(double[] smax) {
93
                this.secondMaxByteUnsigned = smax;
94
        }
95
        
96
        /**
97
         * Asigna el valor m?dio del grid
98
         * @return Valor medio
99
         */
100
        public void setMean(double[] mean) {
101
                this.mean = mean;
102
        }
103

    
104
        /**
105
         * Asigna el valor m?ximo del grid
106
         * @return Valor m?nimo
107
         */
108
        public void setMin(double[] min) {
109
                this.min = min;
110
        }
111

    
112
        /**
113
         * Asigna el valor del segundo m?nimo
114
         * @return Valor del segundo m?nimo
115
         */
116
        public void setSecondMin(double[] smin) {
117
                this.secondMin = smin;
118
        }
119
        
120
        /**
121
         * Asigna el valor m?ximo del grid
122
         * @return Valor m?nimo
123
         */
124
        public void setMinRGB(double[] min) {
125
                this.minByteUnsigned = min;
126
        }
127

    
128
        /**
129
         * Asigna el valor del segundo m?nimo
130
         * @return Valor del segundo m?nimo
131
         */
132
        public void setSecondMinRGB(double[] smin) {
133
                this.secondMinByteUnsigned = smin;
134
        }
135
        
136
        /**
137
         * Asigna la varianza
138
         * @return Varianza
139
         */
140
        public void setVariance(double[] variance) {
141
                this.variance = variance;
142
        }
143
        
144
        /*
145
         * (non-Javadoc)
146
         * @see org.gvsig.raster.hierarchy.IStatistics#getMin()
147
         */
148
        public double[] getMin() {
149
                return min;
150
        }
151
        
152
        /*
153
         * (non-Javadoc)
154
         * @see org.gvsig.raster.hierarchy.IStatistics#getMax()
155
         */
156
        public double[] getMax() {
157
                return max;
158
        }
159
        
160
        /*
161
         * (non-Javadoc)
162
         * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMax()
163
         */
164
        public double[] getSecondMax() {
165
                return secondMax;
166
        }
167
        
168
        /*
169
         * (non-Javadoc)
170
         * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMin()
171
         */
172
        public double[] getSecondMin() {
173
                return secondMin;
174
        }
175
        
176
        /*
177
         * (non-Javadoc)
178
         * @see org.gvsig.raster.hierarchy.IStatistics#getMinRGB()
179
         */
180
        public double[] getMinByteUnsigned() {
181
                return minByteUnsigned;
182
        }
183
        
184
        /*
185
         * (non-Javadoc)
186
         * @see org.gvsig.raster.hierarchy.IStatistics#getMaxRGB()
187
         */
188
        public double[] getMaxByteUnsigned() {
189
                return maxByteUnsigned;
190
        }
191
        
192
        /*
193
         * (non-Javadoc)
194
         * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMaxRGB()
195
         */
196
        public double[] getSecondMaxByteUnsigned() {
197
                return secondMaxByteUnsigned;
198
        }
199
        
200
        /*
201
         * (non-Javadoc)
202
         * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMinRGB()
203
         */
204
        public double[] getSecondMinByteUnsigned() {
205
                return secondMinByteUnsigned;
206
        }
207
        
208
        /*
209
         * (non-Javadoc)
210
         * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMaximun()
211
         */
212
        public double getMaximun() {
213
                double m = Double.NEGATIVE_INFINITY;
214
                for (int i = 0; i < max.length; i++)
215
                        m = Math.max(m, max[i]);
216
                return m;
217
        }
218
        
219
        /*
220
         * (non-Javadoc)
221
         * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMinimun()
222
         */
223
        public double getMinimun() {
224
                double m = Double.MAX_VALUE;
225
                for (int i = 0; i < min.length; i++)
226
                        m = Math.min(m, min[i]);
227
                return m;
228
        }
229

    
230
        /*
231
         * (non-Javadoc)
232
         * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMaximunByteUnsigned()
233
         */
234
        public double getMaximunByteUnsigned() {
235
                double m = Double.NEGATIVE_INFINITY;
236
                for (int i = 0; i < maxByteUnsigned.length; i++)
237
                        m = Math.max(m, maxByteUnsigned[i]);
238
                return m;
239
        }
240

    
241
        /*
242
         * (non-Javadoc)
243
         * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMinimunByteUnsigned()
244
         */
245
        public double getMinimunByteUnsigned() {
246
                double m = Double.MAX_VALUE;
247
                for (int i = 0; i < minByteUnsigned.length; i++)
248
                        m = Math.min(m, minByteUnsigned[i]);
249
                return m;
250
        }
251

    
252
        /*
253
         * (non-Javadoc)
254
         * @see org.gvsig.raster.hierarchy.IStatistics#getMean()
255
         */
256
        public double[] getMean() {
257
                return mean;
258
        }
259

    
260
        /*
261
         * (non-Javadoc)
262
         * @see org.gvsig.raster.hierarchy.IStatistics#getVariance()
263
         */
264
        public double[] getVariance() {
265
                return variance;
266
        }
267
        
268
        /*
269
         * (non-Javadoc)
270
         * @see org.gvsig.raster.hierarchy.IStatistics#getBandCount()
271
         */
272
        public int getBandCount() {
273
                return this.bandCount;
274
        }
275
        
276
        /**
277
         * Asigna el n?mero de bandas
278
         * @param bandCount
279
         */
280
        public void setBandCount(int bandCount) {
281
                this.bandCount = bandCount;
282
        }
283
        
284
        /*
285
         * (non-Javadoc)
286
         * @see org.gvsig.raster.hierarchy.IStatistics#calcFullStatistics(double)
287
         */
288
        public void calculate(double scale) throws FileNotOpenException, RasterDriverException, ProcessInterruptedException {
289
                if (provider == null)
290
                        return;
291
                
292
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
293
                percent = 0;
294
                provider.selectSubdataset();
295
                
296
                // Si no se fuerza su calculo, intentamos ver si estan calculadas y sino
297
                // las intentamos cargar del RMF
298
                if (!forceToRecalc) {
299
                        if (!isCalculated()) {
300
                                try {
301
                                        provider.loadObjectFromRmf(SimpleProviderStatistics.class, this);
302
                                } catch (RmfSerializerException e) {
303
                                        // Si no se puede cargar del RMF, recalcularemos las estadisticas.
304
                                }
305
                        }
306
                        if (isCalculated())
307
                                return;
308
                }
309

    
310
                bandCount = provider.getBandCount();
311
                max = new double[bandCount];
312
                min = new double[bandCount];
313
                secondMax = new double[bandCount];
314
                secondMin = new double[bandCount];
315
                maxByteUnsigned = new double[bandCount];
316
                minByteUnsigned = new double[bandCount];
317
                secondMaxByteUnsigned = new double[bandCount];
318
                secondMinByteUnsigned = new double[bandCount];
319
                mean = new double[bandCount];
320
                variance = new double[bandCount];
321

    
322
                int blockHeight = RasterLibrary.blockHeight;
323
                nValues = new long[bandCount];
324
                boolean[] initializedBand = new boolean[bandCount];
325
                int[] type = new int[bandCount];
326
                byte[][][] b = null;
327
                short[][][] s = null;
328
                int[][][] i = null;
329
                float[][][] f = null;
330
                double[][][] d = null;
331
                double z = 0;
332
                double rgb = 0;
333

    
334
                for (int iBand = 0; iBand < bandCount; iBand++) {
335
                        max[iBand] = Double.NEGATIVE_INFINITY;
336
                        min[iBand] = Double.POSITIVE_INFINITY;
337
                        secondMax[iBand] = Double.NEGATIVE_INFINITY;
338
                        secondMin[iBand] = Double.POSITIVE_INFINITY;
339
                        maxByteUnsigned[iBand] = 0;
340
                        minByteUnsigned[iBand] = 255;
341
                        secondMaxByteUnsigned[iBand] = 0;
342
                        secondMinByteUnsigned[iBand] = 255;
343
                        initializedBand[iBand] = false;
344
                        type[iBand] = provider.getDataType()[iBand];
345
                }
346
                
347
                Buffer refToBuffer = null;
348

    
349
                for (int height = 0; height < provider.getHeight(); height += blockHeight) {
350
                        Object buf = null;
351
                        try {
352
                                buf = provider.readBlock(height, blockHeight, scale);
353
                                if(buf == null)
354
                                        return;
355
                                if(buf instanceof Buffer) {
356
                                        refToBuffer = (Buffer)buf; //Guardamos la referencia para hacer un dispose al acabar
357
                                        buf = getDataFromBuffer(type, (Buffer)buf);
358
                                }
359

    
360
                                switch (type[0]) {
361
                                case Buffer.TYPE_BYTE:          b = (byte[][][]) buf; break;
362
                                case Buffer.TYPE_SHORT:  s = (short[][][]) buf; break;
363
                                case Buffer.TYPE_FLOAT:  f = (float[][][]) buf; break;
364
                                case Buffer.TYPE_DOUBLE: d = (double[][][]) buf; break;
365
                                case Buffer.TYPE_INT:    i = (int[][][]) buf; break;
366
                                }
367

    
368
                        } catch (InvalidSetViewException e) {
369
                                // La vista se asigna autom?ticamente
370
                                return;
371
                        }
372

    
373
                        int h = (int)(blockHeight * scale);
374
                        int datasetWidth = (int)(provider.getWidth() * scale);
375
                        int datasetHeight = (int)(provider.getHeight() * scale);
376
                        int scaledHeight = (int) (height * scale);
377
                        
378
                        if ((scaledHeight + h) > datasetHeight)
379
                                h = datasetHeight - scaledHeight;
380
                        
381
                        for (int iBand = 0; iBand < bandCount; iBand++) {
382
                                for (int col = 0; col < datasetWidth; col++) {
383
                                        for (int row = 0; row < h; row++) {
384
                                                z = (b != null) ? b[iBand][row][col] :
385
                                                                (s != null) ? s[iBand][row][col] :
386
                                                                (d != null) ? d[iBand][row][col] :
387
                                                                (f != null) ? f[iBand][row][col] :
388
                                                                (i != null) ? i[iBand][row][col] :
389
                                                                0;
390
                                                                
391
                                                if ((provider.getNoDataValue().isDefined()) && 
392
                                                        (z == provider.getNoDataValue().getValue().doubleValue()))
393
                                                        continue;
394

    
395
                                                if (Double.isNaN(z) || Double.isInfinite(z))
396
                                                        continue;
397

    
398
                                                rgb = 0;
399
                                                if(b != null) {
400
                                                        rgb = ((byte) z) & 0xff;
401
                                                        mean[iBand] += rgb;
402
                                                        variance[iBand] += rgb * rgb;
403
                                                } else {
404
                                                        //rgb = (b != null) ? ((byte) z) & 0xff : 0;
405
                                                        mean[iBand] += z;
406
                                                        variance[iBand] += z * z;
407
                                                }
408
                                                nValues[iBand]++;
409

    
410
                                                if (!initializedBand[iBand]) {
411
                                                        secondMin[iBand] = min[iBand];
412
                                                        secondMax[iBand] = max[iBand];
413
                                                        min[iBand] = z;
414
                                                        max[iBand] = z;
415
                                                        secondMinByteUnsigned[iBand] = minByteUnsigned[iBand];
416
                                                        secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand];
417
                                                        minByteUnsigned[iBand] = rgb;
418
                                                        maxByteUnsigned[iBand] = rgb;
419
                                                        initializedBand[iBand] = true;
420
                                                        continue;
421
                                                }
422

    
423
                                                if (z < secondMin[iBand]) {
424
                                                        if (z < min[iBand]) {
425
                                                                secondMin[iBand] = min[iBand];
426
                                                                min[iBand] = z;
427
                                                        } else {
428
                                                                if (z > min[iBand])
429
                                                                        secondMin[iBand] = z;
430
                                                        }
431
                                                }
432

    
433
                                                if (z > secondMax[iBand]) {
434
                                                        if (z > max[iBand]) {
435
                                                                secondMax[iBand] = max[iBand];
436
                                                                max[iBand] = z;
437
                                                        } else {
438
                                                                if (z < max[iBand])
439
                                                                        secondMax[iBand] = z;
440
                                                        }
441
                                                }
442

    
443
                                                if (rgb < secondMinByteUnsigned[iBand]) {
444
                                                        if (rgb < minByteUnsigned[iBand]) {
445
                                                                secondMinByteUnsigned[iBand] = minByteUnsigned[iBand];
446
                                                                minByteUnsigned[iBand] = rgb;
447
                                                        } else {
448
                                                                if (rgb > minByteUnsigned[iBand])
449
                                                                        secondMinByteUnsigned[iBand] = rgb;
450
                                                        }
451
                                                }
452

    
453
                                                if (rgb > secondMaxByteUnsigned[iBand]) {
454
                                                        if (rgb > maxByteUnsigned[iBand]) {
455
                                                                secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand];
456
                                                                maxByteUnsigned[iBand] = rgb;
457
                                                        } else {
458
                                                                if (rgb < maxByteUnsigned[iBand])
459
                                                                        secondMaxByteUnsigned[iBand] = rgb;
460
                                                        }
461
                                                }
462
                                        }
463
                                }
464
                                if (task.getEvent() != null)
465
                                        task.manageEvent(task.getEvent());
466
                        }
467
                        percent = ((height * 100) / datasetHeight);
468
                        
469
                        if(refToBuffer != null && refToBuffer instanceof Buffer)
470
                                ((Buffer)refToBuffer).dispose();
471
                        buf = null;
472
                }
473
                percent = 100;
474

    
475
                for (int iBand = 0; iBand < bandCount; iBand++) {
476
                        if (nValues[iBand] > 0) {
477
                                mean[iBand] = mean[iBand] / (double) nValues[iBand];
478
                                variance[iBand] = variance[iBand] / (double) nValues[iBand] - mean[iBand] * mean[iBand];
479
                        }
480
                }
481

    
482
                calculated = true;
483
                forceToRecalc = false;
484
                try {
485
                        provider.saveObjectToRmf(SimpleProviderStatistics.class, this);
486
                } catch (RmfSerializerException e) {
487
                        // No salva a rmf
488
                }
489
        }
490
        
491
        /**
492
         * Gets an array of data from a buffer 
493
         * @param type
494
         * @param buf
495
         * @return
496
         */
497
        private Object getDataFromBuffer(int[] type, Buffer buf) {
498
                byte[][][] b = null;
499
                short[][][] s = null;
500
                int[][][] i = null;
501
                float[][][] f = null;
502
                double[][][] d = null;
503
                switch (type[0]) {
504
                case Buffer.TYPE_BYTE:
505
                        b = new byte[((Buffer)buf).getBandCount()][((Buffer)buf).getHeight()][0];
506
                        for (int j = 0; j < ((Buffer)buf).getHeight(); j++) { 
507
                                 byte[][] line = ((Buffer)buf).getLineByte(j);
508
                                 for (int k = 0; k < line.length; k++) {
509
                                        b[k][j] = line[k];
510
                                 }
511
                        }
512
                        return b;
513
                case Buffer.TYPE_SHORT:
514
                        s = new short[((Buffer)buf).getBandCount()][((Buffer)buf).getHeight()][0];
515
                        for (int j = 0; j < ((Buffer)buf).getHeight(); j++) { 
516
                                 short[][] line = ((Buffer)buf).getLineShort(j);
517
                                 for (int k = 0; k < line.length; k++) {
518
                                        s[k][j] = line[k];
519
                                 }
520
                        }
521
                        return s;
522
                case Buffer.TYPE_FLOAT:
523
                        f = new float[((Buffer)buf).getBandCount()][((Buffer)buf).getHeight()][0];
524
                        for (int j = 0; j < ((Buffer)buf).getHeight(); j++) { 
525
                                 float[][] line = ((Buffer)buf).getLineFloat(j);
526
                                 for (int k = 0; k < line.length; k++) {
527
                                        f[k][j] = line[k];
528
                                 }
529
                        }
530
                        return f;
531
                case Buffer.TYPE_DOUBLE:
532
                        d = new double[((Buffer)buf).getBandCount()][((Buffer)buf).getHeight()][0];
533
                        for (int j = 0; j < ((Buffer)buf).getHeight(); j++) { 
534
                                 double[][] line = ((Buffer)buf).getLineDouble(j);
535
                                 for (int k = 0; k < line.length; k++) {
536
                                        d[k][j] = line[k];
537
                                 }
538
                        }
539
                        return d;
540
                case Buffer.TYPE_INT:
541
                        i = new int[((Buffer)buf).getBandCount()][((Buffer)buf).getHeight()][0];
542
                        for (int j = 0; j < ((Buffer)buf).getHeight(); j++) { 
543
                                 int[][] line = ((Buffer)buf).getLineInt(j);
544
                                 for (int k = 0; k < line.length; k++) {
545
                                        i[k][j] = line[k];
546
                                 }
547
                        }
548
                        return i;
549
                }
550
                return null;
551
        }
552
        
553
        /*
554
         * (non-Javadoc)
555
         * @see org.gvsig.raster.hierarchy.IStatistics#isCalculated()
556
         */
557
        public boolean isCalculated() {
558
                return calculated;
559
        }
560
        
561
        /**
562
         * Asigna el flag de estad?sticas calculadas.
563
         * @param calc
564
         */
565
        public void setCalculated(boolean calc) {
566
                calculated = calc;
567
        }
568
        
569
        /*
570
         * (non-Javadoc)
571
         * @see org.gvsig.raster.hierarchy.IStatistics#setTailTrimValue(double, java.lang.Object)
572
         */
573
        public void setTailTrimValue(double percent, Object valueByBand){
574
                tailTrim.put(percent + "", valueByBand);
575
                for (int i = 0; i < tailTrimValues.size(); i++) {
576
                        if(tailTrimValues.get(i).equals(percent + "")) {
577
                                tailTrimValues.set(i, percent + "");
578
                                return;
579
                        }
580
                }
581
                tailTrimValues.add(percent + "");
582
        }
583
        
584
        /*
585
         * (non-Javadoc)
586
         * @see org.gvsig.raster.hierarchy.IStatistics#getTailTrimValue(double)
587
         */
588
        public Object getTailTrimValue(double percent){
589
                return tailTrim.get(percent + "");
590
        }
591
        
592
        /*
593
         *  (non-Javadoc)
594
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimValue(int)
595
         */
596
        public Object[] getTailTrimValue(int pos) {
597
                return new Object[] { Double.valueOf(Double.parseDouble(tailTrimValues.get(pos) + "")), tailTrim.get(tailTrimValues.get(pos)) };
598
        }
599
        
600
        /*
601
         *  (non-Javadoc)
602
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimCount()
603
         */
604
        public int getTailTrimCount() {
605
                return tailTrimValues.size();
606
        }
607

    
608
        /**
609
         * Pone a cero el porcentaje de progreso del proceso de calculo de histograma
610
         */
611
        public void resetPercent() {
612
                percent = 0;
613
        }
614

    
615
        /**
616
         * Obtiene el porcentaje de progreso del proceso de calculo de histograma
617
         * @return porcentaje de progreso
618
         */
619
        public int getPercent() {
620
                return percent;
621
        }
622

    
623
        /**
624
         * Cuando se llama a este m?todo fuerza que la siguiente petici?n de estad?sticas 
625
         * no sea le?da de RMF y sean recalculadas por completo.
626
         * @param forceToRecalc
627
         */
628
        public void forceToRecalc() {
629
                this.forceToRecalc = true;
630
        }
631
        
632
        /**
633
         * Joins the this statistic object with the parameter and
634
         * returns a new Statistics object.
635
         * @param stats
636
         * @return
637
         */
638
        public static Statistics union(RasterProvider prov, ArrayList<RasterProvider> list) {
639
                SimpleProviderStatistics s = new SimpleProviderStatistics(prov);
640
                boolean isCalculated = true;
641
                
642
                for (int i = 0; i < list.size(); i++) {
643
                        Statistics newStat = list.get(i).getStatistics();
644
                        
645
                        if(newStat.isCalculated() == false)
646
                                isCalculated = false;
647
                        
648
                        double[] max = s.getMax();
649
                        if(max != null) {
650
                                for (int j = 0; j < max.length; j++) {
651
                                        max[j] = Math.max(max[j], newStat.getMax()[j]);
652
                                }
653
                        }
654

    
655
                        double[] min = s.getMin();
656
                        if(min != null) {
657
                                for (int j = 0; j < min.length; j++) {
658
                                        min[j] = Math.min(min[j], newStat.getMin()[j]);
659
                                }
660
                        }
661

    
662
                        double[] smax = s.getSecondMax();
663
                        if(smax != null) {
664
                                for (int j = 0; j < smax.length; j++) {
665
                                        smax[j] = Math.max(smax[j], newStat.getSecondMax()[j]);
666
                                }
667
                        }
668

    
669
                        double[] smin = s.getSecondMin();
670
                        if(smin != null) {
671
                                for (int j = 0; j < smin.length; j++) {
672
                                        smin[j] = Math.min(smin[j], newStat.getSecondMin()[j]);
673
                                }
674
                        }
675
                        
676
                        double[] maxbu = s.getMaxByteUnsigned();
677
                        if(maxbu != null) {
678
                                for (int j = 0; j < maxbu.length; j++) {
679
                                        maxbu[j] = Math.max(maxbu[j], newStat.getMaxByteUnsigned()[j]);
680
                                }
681
                        }
682

    
683
                        double[] minbu = s.getMinByteUnsigned();
684
                        if(minbu != null) {
685
                                for (int j = 0; j < minbu.length; j++) {
686
                                        minbu[j] = Math.min(minbu[j], newStat.getMinByteUnsigned()[j]);
687
                                }
688
                        }
689

    
690
                        double[] smaxbu = s.getSecondMaxByteUnsigned();
691
                        if(smaxbu != null) {
692
                                for (int j = 0; j < smaxbu.length; j++) {
693
                                        smaxbu[j] = Math.max(smaxbu[j], newStat.getSecondMaxByteUnsigned()[j]);
694
                                }
695
                        }
696

    
697
                        double[] sminbu = s.getSecondMinByteUnsigned();
698
                        if(sminbu != null) {
699
                                for (int j = 0; j < sminbu.length; j++) {
700
                                        sminbu[j] = Math.min(sminbu[j], newStat.getSecondMinByteUnsigned()[j]);
701
                                }
702
                        }
703
                        
704
                        double[] mean = s.getMean();
705
                        if(mean != null) {
706
                                for (int j = 0; j < mean.length; j++) {
707
                                        mean[j] = (mean[j] + newStat.getMean()[j]) / 2;
708
                                }
709
                        }
710
                        
711
                        double[] var = s.getVariance();
712
                        long[] values = s.getNumberOfValues();
713
                        if(var != null) {
714
                                for (int j = 0; j < var.length; j++) {
715
                                        var[j] = (var[j] + newStat.getVariance()[j]) / (values[j] + newStat.getNumberOfValues()[j]) - mean[j] * mean[j];
716
                                }
717
                        }
718
                }
719
                s.setCalculated(isCalculated);
720
                try {
721
                        prov.saveObjectToRmf(SimpleProviderStatistics.class, s);
722
                } catch (RmfSerializerException e) {
723
                        // No salva a rmf
724
                }
725
                return s;
726
        }
727
        
728
        /*
729
         * (non-Javadoc)
730
         * @see org.gvsig.fmap.dal.coverage.store.props.Statistics#cloneStatistics()
731
         */
732
        public Statistics cloneStatistics() {
733
                SimpleProviderStatistics s = new SimpleProviderStatistics(provider);
734
                return super.cloneStatistics(s);
735
        }
736

    
737
}