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 / DataStoreStatistics.java @ 162

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

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

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

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

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

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

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

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

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

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

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

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

    
331
                for (int iBand = 0; iBand < bandCount; iBand++) {
332
                        max[iBand] = Double.NEGATIVE_INFINITY;
333
                        min[iBand] = Double.POSITIVE_INFINITY;
334
                        secondMax[iBand] = Double.NEGATIVE_INFINITY;
335
                        secondMin[iBand] = Double.POSITIVE_INFINITY;
336
                        maxByteUnsigned[iBand] = 0;
337
                        minByteUnsigned[iBand] = 255;
338
                        secondMaxByteUnsigned[iBand] = 0;
339
                        secondMinByteUnsigned[iBand] = 255;
340
                        initializedBand[iBand] = false;
341
                        type[iBand] = provider.getDataType()[iBand];
342
                }
343

    
344
                for (int height = 0; height < provider.getHeight(); height += blockHeight) {
345
                        try {
346
                                Object buf = provider.readBlock(height, blockHeight);
347
                                switch (type[0]) {
348
                                        case Buffer.TYPE_BYTE:          b = (byte[][][]) buf; break;
349
                                        case Buffer.TYPE_SHORT:  s = (short[][][]) buf; break;
350
                                        case Buffer.TYPE_FLOAT:  f = (float[][][]) buf; break;
351
                                        case Buffer.TYPE_DOUBLE: d = (double[][][]) buf; break;
352
                                        case Buffer.TYPE_INT:    i = (int[][][]) buf; break;
353
                                }
354
                        } catch (InvalidSetViewException e) {
355
                                // La vista se asigna autom?ticamente
356
                                return;
357
                        }
358
                        
359
                        int hB = blockHeight;
360
                        if ((height + hB) > provider.getHeight())
361
                                hB = ((int)provider.getHeight()) - height;
362
                        for (int iBand = 0; iBand < bandCount; iBand++) {
363
                                for (int col = 0; col < provider.getWidth(); col++) {
364
                                        for (int row = 0; row < hB; row++) {
365
                                                z = (b != null) ? b[iBand][row][col] :
366
                                                                (s != null) ? s[iBand][row][col] :
367
                                                                (d != null) ? d[iBand][row][col] :
368
                                                                (f != null) ? f[iBand][row][col] :
369
                                                                (i != null) ? i[iBand][row][col] :
370
                                                                0;
371

    
372
                                                if (provider.isNoDataEnabled() && (z == provider.getNoDataValue()))
373
                                                        continue;
374

    
375
                                                if (Double.isNaN(z))
376
                                                        continue;
377

    
378
                                                rgb = 0;
379
                                                if(b != null) {
380
                                                        rgb = ((byte) z) & 0xff;
381
                                                        mean[iBand] += rgb;
382
                                                        variance[iBand] += rgb * rgb;
383
                                                } else {
384
                                                        //rgb = (b != null) ? ((byte) z) & 0xff : 0;
385
                                                        mean[iBand] += z;
386
                                                        variance[iBand] += z * z;
387
                                                }
388
                                                iValues[iBand]++;
389

    
390
                                                if (!initializedBand[iBand]) {
391
                                                        secondMin[iBand] = min[iBand];
392
                                                        secondMax[iBand] = max[iBand];
393
                                                        min[iBand] = z;
394
                                                        max[iBand] = z;
395
                                                        secondMinByteUnsigned[iBand] = minByteUnsigned[iBand];
396
                                                        secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand];
397
                                                        minByteUnsigned[iBand] = rgb;
398
                                                        maxByteUnsigned[iBand] = rgb;
399
                                                        initializedBand[iBand] = true;
400
                                                        continue;
401
                                                }
402

    
403
                                                if (z < secondMin[iBand]) {
404
                                                        if (z < min[iBand]) {
405
                                                                secondMin[iBand] = min[iBand];
406
                                                                min[iBand] = z;
407
                                                        } else {
408
                                                                if (z > min[iBand])
409
                                                                        secondMin[iBand] = z;
410
                                                        }
411
                                                }
412

    
413
                                                if (z > secondMax[iBand]) {
414
                                                        if (z > max[iBand]) {
415
                                                                secondMax[iBand] = max[iBand];
416
                                                                max[iBand] = z;
417
                                                        } else {
418
                                                                if (z < max[iBand])
419
                                                                        secondMax[iBand] = z;
420
                                                        }
421
                                                }
422

    
423
                                                if (rgb < secondMinByteUnsigned[iBand]) {
424
                                                        if (rgb < minByteUnsigned[iBand]) {
425
                                                                secondMinByteUnsigned[iBand] = minByteUnsigned[iBand];
426
                                                                minByteUnsigned[iBand] = rgb;
427
                                                        } else {
428
                                                                if (rgb > minByteUnsigned[iBand])
429
                                                                        secondMinByteUnsigned[iBand] = rgb;
430
                                                        }
431
                                                }
432

    
433
                                                if (rgb > secondMaxByteUnsigned[iBand]) {
434
                                                        if (rgb > maxByteUnsigned[iBand]) {
435
                                                                secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand];
436
                                                                maxByteUnsigned[iBand] = rgb;
437
                                                        } else {
438
                                                                if (rgb < maxByteUnsigned[iBand])
439
                                                                        secondMaxByteUnsigned[iBand] = rgb;
440
                                                        }
441
                                                }
442
                                        }
443
                                }
444
                                if (task.getEvent() != null)
445
                                        task.manageEvent(task.getEvent());
446
                        }
447
                        percent = ((height * 100) / (int)provider.getHeight());
448
                }
449
                percent = 100;
450

    
451
                for (int iBand = 0; iBand < bandCount; iBand++) {
452
                        if (iValues[iBand] > 0) {
453
                                mean[iBand] = mean[iBand] / (double) iValues[iBand];
454
                                variance[iBand] = variance[iBand] / (double) iValues[iBand] - mean[iBand] * mean[iBand];
455
                        }
456
                }
457

    
458
                calculated = true;
459
                forceToRecalc = false;
460
                try {
461
                        provider.saveObjectToRmf(DataStoreStatistics.class, this);
462
                } catch (RmfSerializerException e) {
463
                        // No salva a rmf
464
                }
465
        }
466

    
467
        /*
468
         * (non-Javadoc)
469
         * @see org.gvsig.raster.hierarchy.IStatistics#isCalculated()
470
         */
471
        public boolean isCalculated() {
472
                return calculated;
473
        }
474
        
475
        /**
476
         * Asigna el flag de estad?sticas calculadas.
477
         * @param calc
478
         */
479
        public void setCalculated(boolean calc) {
480
                calculated = calc;
481
        }
482
        
483
        /*
484
         * (non-Javadoc)
485
         * @see org.gvsig.raster.hierarchy.IStatistics#setTailTrimValue(double, java.lang.Object)
486
         */
487
        public void setTailTrimValue(double percent, Object valueByBand){
488
                tailTrim.put(percent + "", valueByBand);
489
                for (int i = 0; i < tailTrimValues.size(); i++) {
490
                        if(tailTrimValues.get(i).equals(percent + "")) {
491
                                tailTrimValues.set(i, percent + "");
492
                                return;
493
                        }
494
                }
495
                tailTrimValues.add(percent + "");
496
        }
497
        
498
        /*
499
         * (non-Javadoc)
500
         * @see org.gvsig.raster.hierarchy.IStatistics#getTailTrimValue(double)
501
         */
502
        public Object getTailTrimValue(double percent){
503
                return tailTrim.get(percent + "");
504
        }
505
        
506
        /*
507
         *  (non-Javadoc)
508
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimValue(int)
509
         */
510
        public Object[] getTailTrimValue(int pos) {
511
                return new Object[] { Double.valueOf(Double.parseDouble(tailTrimValues.get(pos) + "")), tailTrim.get(tailTrimValues.get(pos)) };
512
        }
513
        
514
        /*
515
         *  (non-Javadoc)
516
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimCount()
517
         */
518
        public int getTailTrimCount() {
519
                return tailTrimValues.size();
520
        }
521

    
522
        /**
523
         * Pone a cero el porcentaje de progreso del proceso de calculo de histograma
524
         */
525
        public void resetPercent() {
526
                percent = 0;
527
        }
528

    
529
        /**
530
         * Obtiene el porcentaje de progreso del proceso de calculo de histograma
531
         * @return porcentaje de progreso
532
         */
533
        public int getPercent() {
534
                return percent;
535
        }
536

    
537
        /**
538
         * Cuando se llama a este m?todo fuerza que la siguiente petici?n de estad?sticas 
539
         * no sea le?da de RMF y sean recalculadas por completo.
540
         * @param forceToRecalc
541
         */
542
        public void forceToRecalc() {
543
                this.forceToRecalc = true;
544
        }
545

    
546
}