Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / properties / DatasetStatistics.java @ 12254

History | View | Annotate | Download (9.64 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.dataset.properties;
20

    
21
import java.io.File;
22
import java.util.ArrayList;
23
import java.util.Date;
24
import java.util.Hashtable;
25

    
26
import org.gvsig.raster.RasterLibrary;
27
import org.gvsig.raster.dataset.FileNotOpenException;
28
import org.gvsig.raster.dataset.IBuffer;
29
import org.gvsig.raster.dataset.InvalidSetViewException;
30
import org.gvsig.raster.dataset.RasterDataset;
31
import org.gvsig.raster.dataset.RasterDriverException;
32
import org.gvsig.raster.shared.IStatistics;
33

    
34

    
35
/**
36
 * Estadisticas asociadas a un fichero raster.
37
 *  
38
 * @author Nacho Brodin (nachobrodin@gmail.com)
39
 */
40
public class DatasetStatistics implements IStatistics{
41
        public static final int                CANCEL_FULLSTAT = 1;
42
        private boolean[]                        cancel = new boolean[1];
43
        
44
        /*
45
         * Esta a false si las estadisticas no son del fichero completo. Esto es posible porque podemos
46
         * tener unas estad?sticas calculadas a partir de una petici?n con subsampleo. Hay que tener en
47
         * cuenta que el raster puede ser muy grande y este calculo muy costoso.
48
         */
49
        protected boolean                                complete = false;
50
        protected double[]                         max = null;
51
        protected double[]                         min = null;
52
        protected double[]                         secondMax = null;
53
        protected double[]                         secondMin = null;
54
        protected double[]                         mean = null;
55
        protected double[]                         variance = null;
56

    
57
        protected String                                 fName = null;
58
        protected RasterDataset                grf = null;
59
        protected boolean                                calculated = false;
60
        protected Hashtable                        tailTrim = new Hashtable();
61
        protected ArrayList                        tailTrimValues = new ArrayList();
62
        
63
        /**
64
         * Constructor. Asigna el fichero asociado.
65
         */
66
        public DatasetStatistics(RasterDataset grf){
67
                this.grf = grf;
68
        }
69
        
70
        /**
71
         * Asigna el valor m?ximo del grid
72
         * @return Valor m?ximo
73
         */
74
        public void setMax(double[] max) {
75
                this.max = max;
76
        }
77

    
78
        /**
79
         * Asigna el valor del segundo m?ximo
80
         * @return Valor del segundo m?ximo
81
         */
82
        public void setSecondMax(double[] smax) {
83
                this.secondMax = smax;
84
        }
85
        
86
        /**
87
         * Asigna el valor m?dio del grid
88
         * @return Valor medio
89
         */
90
        public void setMean(double[] mean) {
91
                this.mean = mean;
92
        }
93

    
94
        /**
95
         * Asigna el valor m?ximo del grid
96
         * @return Valor m?nimo
97
         */
98
        public void setMin(double[] min) {
99
                this.min = min;
100
        }
101

    
102
        /**
103
         * Asigna el valor del segundo m?nimo
104
         * @return Valor del segundo m?nimo
105
         */
106
        public void setSecondMin(double[] smin) {
107
                this.secondMin = smin;
108
        }
109
        
110
        /**
111
         * Asigna la varianza
112
         * @return Varianza
113
         */
114
        public void setVariance(double[] variance) {
115
                this.variance = variance;
116
        }
117
        
118
        /*
119
         *  (non-Javadoc)
120
         * @see org.gvsig.fmap.driver.IStatistics#getMax()
121
         */
122
        public double[] getMax() {
123
                return max;
124
        }
125
        
126
        /*
127
         *  (non-Javadoc)
128
         * @see org.gvsig.fmap.driver.IStatistics#getSecondMax()
129
         */
130
        public double[] getSecondMax() {
131
                return secondMax;
132
        }
133
        
134
        /*
135
         *  (non-Javadoc)
136
         * @see org.gvsig.fmap.driver.IStatistics#getSecondMin()
137
         */
138
        public double[] getSecondMin() {
139
                return secondMin;
140
        }
141
        
142
        /*
143
         *  (non-Javadoc)
144
         * @see org.gvsig.fmap.driver.IStatistics#getMaximun()
145
         */
146
        public double getMaximun(){
147
                double m = Double.NEGATIVE_INFINITY;
148
                for(int i = 0; i < max.length; i++)
149
                        m = Math.max(m, max[i]);
150
                return m;
151
        }
152
        
153
        /*
154
         *  (non-Javadoc)
155
         * @see org.gvsig.fmap.driver.IStatistics#getMinimun()
156
         */
157
        public double getMinimun(){
158
                double m = Double.MAX_VALUE;
159
                for(int i = 0; i < min.length; i++)
160
                        m = Math.min(m, min[i]);
161
                return m;
162
        }
163

    
164
        /*
165
         *  (non-Javadoc)
166
         * @see org.gvsig.fmap.driver.IStatistics#getMean()
167
         */
168
        public double[] getMean() {
169
                return mean;
170
        }
171

    
172
        /*
173
         *  (non-Javadoc)
174
         * @see org.gvsig.fmap.driver.IStatistics#getMin()
175
         */
176
        public double[] getMin() {
177
                return min;
178
        }
179

    
180
        /*
181
         *  (non-Javadoc)
182
         * @see org.gvsig.fmap.driver.IStatistics#getVariance()
183
         */
184
        public double[] getVariance() {
185
                return variance;
186
        }
187
        
188
        /*
189
         *  (non-Javadoc)
190
         * @see org.gvsig.fmap.driver.IStatistics#getBandCount()
191
         */
192
        public int getBandCount(){
193
                return grf.getBandCount();
194
        }
195
        
196
        /*
197
         *  (non-Javadoc)
198
         * @see org.gvsig.fmap.driver.IStatistics#calcFullStatistics()
199
         */
200
        public void calcFullStatistics() throws FileNotOpenException, RasterDriverException{
201
                long t2;
202
                long t1 = new Date().getTime();
203
                int type = grf.getDataType();
204
                max = new double[grf.getBandCount()];
205
                min = new double[grf.getBandCount()];
206
                secondMax = new double[grf.getBandCount()];
207
                secondMin = new double[grf.getBandCount()];
208
                mean = new double[grf.getBandCount()];
209
                variance = new double[grf.getBandCount()];
210
                long[] iValues = new long[grf.getBandCount()];
211
                boolean[] init = new boolean[grf.getBandCount()];
212

    
213
                byte[][][] b = null;
214
                short[][][] s = null;
215
                int[][][] i = null;
216
                float[][][] f = null;
217
                double[][][] d = null;
218
        
219
                for (int iBand = 0; iBand < grf.getBandCount(); iBand ++) {
220
                        max[iBand] = Double.NEGATIVE_INFINITY; 
221
                        min[iBand] = Double.POSITIVE_INFINITY;
222
                        secondMax[iBand] = Double.NEGATIVE_INFINITY; 
223
                        secondMin[iBand] = Double.POSITIVE_INFINITY;
224
                        init[iBand] = true;
225
                }
226
                
227
                int h = RasterLibrary.blockHeight;
228
                for (int block = 0; block < grf.getHeight(); block += h) {                        
229
                        Object buf = null;
230
                        try {
231
                                buf = grf.readBlock(block, RasterLibrary.blockHeight);
232
                        } catch (InvalidSetViewException e) {
233
                                //La vista se asigna autom?ticamente
234
                        }
235
                        switch(type){
236
                        case IBuffer.TYPE_BYTE:                b = (byte[][][])buf;break;
237
                        case IBuffer.TYPE_SHORT:         s = (short[][][])buf;break;
238
                        case IBuffer.TYPE_INT:                 i = (int[][][])buf;break;
239
                        case IBuffer.TYPE_FLOAT:         f = (float[][][])buf;break;
240
                        case IBuffer.TYPE_DOUBLE:         d = (double[][][])buf;break;
241
                        }
242
                        
243
                        int hB = RasterLibrary.blockHeight;
244
                        if((block + hB) > grf.getHeight())
245
                                hB = Math.abs(grf.getHeight() - block);
246
                        for (int iBand = 0; iBand < grf.getBandCount(); iBand ++) {
247
                                for (int col = 0; col < grf.getWidth(); col ++) {
248
                                        for (int row = 0; row < hB; row++) {        
249
                                                double z = (b != null) ? (b[iBand][row][col] & 0xff) : ((s != null) ? (s[iBand][row][col] & 0xffff) : ((i != null) ? (i[iBand][row][col] & 0xffffff)  : (f != null) ? f[iBand][row][col] : d[iBand][row][col]));
250
                                                
251
                                                if (init[iBand]) {
252
                                                        min[iBand] = z;
253
                                                        //secondMin[iBand] = z;
254
                                                        max[iBand] = z;
255
                                                        //secondMax[iBand] = z;
256
                                                        init[iBand] = false;
257
                                                } else {
258
                                                        if ( min[iBand] > z ) {
259
                                                                secondMin[iBand] = min[iBand];
260
                                                                min[iBand] = z;
261
                                                        }
262
                                                        
263
                                                        if ( max[iBand] < z ) {
264
                                                                secondMax[iBand] = max[iBand];
265
                                                                max[iBand] = z;
266
                                                        }
267
                                                        
268
                                                        if(z < max[iBand]  && z > secondMax[iBand])
269
                                                                secondMax[iBand] = z;
270

    
271
                                                        if(z > min[iBand]  && z < secondMin[iBand])
272
                                                                secondMin[iBand] = z;
273
                                                }
274
                                                mean[iBand] += z;
275
                                                variance[iBand] += z * z;
276
                                                iValues[iBand]++;
277
                                        }
278
                                        
279
                                        if (isCanceled(CANCEL_FULLSTAT))
280
                                                return;
281
                                }
282
                        }
283
                }
284
                
285
                for (int iBand = 0; iBand < grf.getBandCount(); iBand ++) {
286
                        if( iValues[iBand] > 0 ) {
287
                                mean[iBand] /= (double) iValues[iBand];
288
                                variance[iBand] = variance[iBand] / (double) iValues[iBand] - mean[iBand] * mean[iBand];
289
                        }
290
                }
291
                
292
                calculated = true;
293
                t2 = new Date().getTime();
294
            System.out.println("Estadisticas " + grf.getFName() + ": " + ((t2 - t1) / 1000D) + ", secs.");
295
        }
296
        
297
        /**
298
         * Carga estadisticas desde el fichero Rmf si las hay.
299
         * @param fName Nombre del fichero
300
         */
301
        public void loadFromRmf(){
302
                if(grf != null){
303
                        File f = new File(grf.getFName());
304
                        if(!f.exists())
305
                                return;
306
                        //calculated = true;
307
                        //TODO: FUNCIONALIDAD: Carga de estad?sticas rmf
308
                }
309
        }
310
        
311
        /**
312
         * Salva estad?sticas a fichero rmf.
313
         * @param fName
314
         */
315
        public void saveToRmf(){
316
                //TODO: FUNCIONALIDAD: Salvado de estad?sticas a rmf
317
        }
318

    
319
        /*
320
         *  (non-Javadoc)
321
         * @see org.gvsig.fmap.driver.IStatistics#isCalculated()
322
         */
323
        public boolean isCalculated() {
324
                return calculated;
325
        }
326
        
327
        /*
328
         *  (non-Javadoc)
329
         * @see org.gvsig.fmap.driver.IStatistics#setTailTrimValue(double, java.lang.Object)
330
         */
331
        public void setTailTrimValue(double percent, Object valueByBand){
332
                tailTrim.put(new Double(percent), valueByBand);
333
                tailTrimValues.add(new Double(percent));
334
        }
335
        
336
        /*
337
         *  (non-Javadoc)
338
         * @see org.gvsig.fmap.driver.IStatistics#getTailTrimValue(double)
339
         */
340
        public Object getTailTrimValue(double percent){
341
                return tailTrim.get(new Double(percent));
342
        }
343
        
344
        /*
345
         *  (non-Javadoc)
346
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimValue(int)
347
         */
348
        public Object[] getTailTrimValue(int pos) {
349
                return new Object[]{tailTrimValues.get(pos), tailTrim.get((Double)tailTrimValues.get(pos))};
350
        }
351
        
352
        /*
353
         *  (non-Javadoc)
354
         * @see org.gvsig.raster.shared.IStatistics#getTailTrimCount()
355
         */
356
        public int getTailTrimCount() {
357
                return tailTrimValues.size();
358
        }
359

    
360
        /*
361
         * (non-Javadoc)
362
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
363
         */
364
        public boolean isCanceled(int process) {
365
                if(process == CANCEL_FULLSTAT)
366
                        return cancel[0];
367
                return false;
368
        }
369

    
370
        /*
371
         * (non-Javadoc)
372
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
373
         */
374
        public void setCanceled(boolean value, int process) {
375
                if(process == (CANCEL_FULLSTAT | 0))
376
                        cancel[0] = value;
377
        }
378
}