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 / SimpleProviderHistogramComputer.java @ 1419

History | View | Annotate | Download (11.1 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.datastruct.BufferHistogram;
29
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
30
import org.gvsig.fmap.dal.coverage.exception.HistogramException;
31
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
32
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
33
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
34
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
35
import org.gvsig.fmap.dal.coverage.store.props.HistogramComputer;
36
import org.gvsig.raster.impl.datastruct.BufferHistogramImpl;
37
import org.gvsig.raster.impl.process.RasterTask;
38
import org.gvsig.raster.impl.process.RasterTaskQueue;
39
import org.gvsig.raster.impl.provider.RasterProvider;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

    
43
/**
44
 * Clase para la gesti?n de histogramas de un raster. Es la encargada del calculo de un histograma
45
 * total o parcial de un raster a partir de los datos de disco. Adem?s tambi?n es la encargada de gestionar
46
 * salvar este histograma a .rmf. En caso de que solicite un histograma del raster completo este ir?
47
 * a buscarlo al fichero rmf asociado antes de calcularlo por si ya existise. Al realizar el calculo
48
 * del histograma de la imagen completa este ser? salvado en el fichero .rmf asociado al raster.
49
 * 
50
 * @author Nacho Brodin (nachobrodin@gmail.com)
51
 */
52
public class SimpleProviderHistogramComputer implements HistogramComputer {
53
        private static final Logger     logger    = LoggerFactory.getLogger(SimpleProviderHistogramComputer.class);
54
        /**
55
         * Histograma de la imagen completa
56
         */
57
        protected BufferHistogramImpl   histogram = null;
58
        /**
59
         * Dataset del cual se calcula el histograma
60
         */
61
        private RasterProvider          provider  = null;
62
        private int                     percent   = 0;
63
        private boolean                 refresh   = false;
64
        
65
        /**
66
         * Constructor
67
         * @param dataset
68
         */
69
        public SimpleProviderHistogramComputer(RasterProvider provider) {
70
                this.provider = provider;
71
        }
72

    
73
        /**
74
         * Obtiene el minimo valor de las estadisticas de un histograma.
75
         * @return double
76
         */
77
        public double getMinimum() {
78
                return provider.getStatistics().getMinimun();
79
        }
80

    
81
        /**
82
         * Obtiene el maximo valor de las estadisticas de un histograma.
83
         * @return double
84
         */
85
        public double getMaximum() {
86
                return provider.getStatistics().getMaximun();
87
        }
88
        /**
89
         * Obtiene el histograma. Si puede conseguirlo del fichero rmf ir? all? a 
90
         * buscarlo sino lo calcular?.
91
         * @return histograma 
92
         */
93
        public BufferHistogram getBufferHistogram() throws HistogramException, ProcessInterruptedException {
94
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
95
                if (provider != null) {
96
                        if(histogram == null || refresh) {
97
                                try {
98
                                        provider.getStatistics().calculate(1);
99
                                } catch (FileNotOpenException e) {
100
                                        throw new HistogramException("");
101
                                } catch (RasterDriverException e) {
102
                                        throw new HistogramException("");
103
                                }
104

    
105
                                try {
106
                                        histogram = (BufferHistogramImpl) provider.loadObjectFromRmf(BufferHistogram.class, histogram);
107
                                        if (histogram != null)
108
                                                return histogram;
109
                                } catch (RmfSerializerException e) {
110
                                        //No carga desde rmf. No afecta a la funcionalidad
111
                                }
112

    
113
                                if(task.getEvent() != null)
114
                                        task.manageEvent(task.getEvent());
115

    
116
                                histogram = new BufferHistogramImpl(provider.getBandCount(), 
117
                                                provider.getStatistics().getMin(), 
118
                                                provider.getStatistics().getMax(), 
119
                                                provider.getDataType()[0]);
120

    
121
                                try {
122
                                        histogram = (BufferHistogramImpl)getHistogramByDataType();
123
                                } catch (FileNotOpenException e) {
124
                                        throw new HistogramException("", e);
125
                                } catch (RasterDriverException e) {
126
                                        throw new HistogramException("", e);
127
                                } catch (Exception e) {
128
                                        logger.info("Error calculando el histograma", e);
129
                                }
130

    
131
                                try {
132
                                        provider.saveObjectToRmf(BufferHistogram.class, histogram);
133
                                } catch (RmfSerializerException e) {
134
                                        //No salva a rmf. No afecta a la funcionalidad
135
                                }
136
                        }
137
                        return histogram;
138

    
139
                }
140
                return null;
141
        }
142
        
143
        /**
144
         * Gets an array of data from a buffer 
145
         * @param type
146
         * @param buf
147
         * @return
148
         */
149
        private void loadHistogramFromBuffer(Buffer buf) {
150
                switch (buf.getDataType()) {
151
                case Buffer.TYPE_BYTE:
152
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
153
                                for (int col = 0; col < buf.getWidth(); col++)
154
                                        for (int row = 0; row < buf.getHeight(); row++)
155
                                                histogram.incrementPxValue(iBand, (double) buf.getElemByte(row, col, iBand));
156
                        break;
157
                case Buffer.TYPE_SHORT:
158
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
159
                                for (int col = 0; col < buf.getWidth(); col++)
160
                                        for (int row = 0; row < buf.getHeight(); row++)
161
                                                histogram.incrementPxValue(iBand, (double) buf.getElemShort(row, col, iBand));
162
                        break;
163
                case Buffer.TYPE_FLOAT:
164
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
165
                                for (int col = 0; col < buf.getWidth(); col++)
166
                                        for (int row = 0; row < buf.getHeight(); row++)
167
                                                histogram.incrementPxValue(iBand, (double) buf.getElemFloat(row, col, iBand));
168
                        break;
169
                case Buffer.TYPE_DOUBLE:
170
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
171
                                for (int col = 0; col < buf.getWidth(); col++)
172
                                        for (int row = 0; row < buf.getHeight(); row++)
173
                                                histogram.incrementPxValue(iBand, (double) buf.getElemDouble(row, col, iBand));
174
                        break;
175
                case Buffer.TYPE_INT:
176
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
177
                                for (int col = 0; col < buf.getWidth(); col++)
178
                                        for (int row = 0; row < buf.getHeight(); row++)
179
                                                histogram.incrementPxValue(iBand, (double) buf.getElemInt(row, col, iBand));
180
                        break;
181
                }
182
        }
183

    
184
        /**
185
         * Obtiene el histograma teniendo en cuenta la lista de clases
186
         * @return Histograma correspondiente a la lista de clases
187
         */
188
        private BufferHistogram getHistogramByDataType() 
189
                throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
190
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
191
                percent = 0;
192
                int type = provider.getDataType()[0];
193
                int h = RasterLibrary.blockHeight;
194

    
195
                if(provider.getNoDataValue().isDefined())
196
                        histogram.setNoDataValue(provider.getNoDataValue());
197
                for (int block = 0; block < provider.getHeight(); block += h) {
198
                        Object buf = null;
199
                        try {
200
                                buf = provider.readBlock(block, h, RasterLibrary.statisticsScale);
201
                        } catch (InvalidSetViewException e) {
202
                                // La vista se asigna autom?ticamente
203
                        }
204

    
205
                        int hB = h;
206
                        if ((block + hB) > provider.getHeight())
207
                                hB = Math.abs(((int)provider.getHeight()) - block);
208
                        
209
                        hB *= RasterLibrary.statisticsScale;
210

    
211
                        if(buf instanceof Buffer) {
212
                                loadHistogramFromBuffer((Buffer)buf);
213
                        } else {
214
                                switch (type) {
215
                                case Buffer.TYPE_BYTE:
216
                                        byte[][][] bBlock = (byte[][][]) buf;
217
                                        for (int iBand = 0; iBand < provider.getBandCount(); iBand++)
218
                                                for (int col = 0; col < bBlock[iBand][0].length; col++)
219
                                                        for (int row = 0; row < hB; row++)
220
                                                                histogram.incrementPxValue(iBand, (double) bBlock[iBand][row][col]);
221
                                        break;
222
                                case Buffer.TYPE_SHORT:
223
                                        short[][][] sBlock = (short[][][]) buf;
224
                                        for (int iBand = 0; iBand < provider.getBandCount(); iBand++)
225
                                                for (int col = 0; col < sBlock[iBand][0].length; col++)
226
                                                        for (int row = 0; row < hB; row++)
227
                                                                histogram.incrementPxValue(iBand, (double) sBlock[iBand][row][col]);
228
                                        break;
229
                                case Buffer.TYPE_INT:
230
                                        int[][][] iBlock = (int[][][]) buf;
231
                                        for (int iBand = 0; iBand < provider.getBandCount(); iBand++)
232
                                                for (int col = 0; col < iBlock[iBand][0].length; col++)
233
                                                        for (int row = 0; row < hB; row++)
234
                                                                histogram.incrementPxValue(iBand, (double) iBlock[iBand][row][col]);
235
                                        break;
236
                                case Buffer.TYPE_FLOAT:
237
                                        float[][][] fBlock = (float[][][]) buf;
238
                                        for (int iBand = 0; iBand < provider.getBandCount(); iBand++)
239
                                                for (int col = 0; col < fBlock[iBand][0].length; col++)
240
                                                        for (int row = 0; row < hB; row++)
241
                                                                histogram.incrementPxValue(iBand, (double) (fBlock[iBand][row][col]));
242
                                        break;
243
                                case Buffer.TYPE_DOUBLE:
244
                                        double[][][] dBlock = (double[][][]) buf;
245
                                        for (int iBand = 0; iBand < provider.getBandCount(); iBand++)
246
                                                for (int col = 0; col < dBlock[iBand][0].length; col++)
247
                                                        for (int row = 0; row < hB; row++)
248
                                                                histogram.incrementPxValue(iBand, (double) (dBlock[iBand][row][col]));
249
                                        break;
250
                                }
251
                        }
252
                        if (task.getEvent() != null)
253
                                task.manageEvent(task.getEvent());
254
                        percent += ((h * 100) / provider.getHeight());
255
                }
256
                percent = 100;
257
                return histogram;
258
        }
259

    
260
        /**
261
         * Pone a cero el porcentaje de progreso del proceso de calculo de histograma
262
         */
263
        public void resetPercent() {
264
                percent = 0;
265
        }
266

    
267
        /**
268
         * Obtiene el porcentaje de progreso del proceso de calculo de histograma
269
         * @return porcentaje de progreso
270
         */
271
        public int getPercent() {
272
                return percent;
273
        }
274

    
275
        /*
276
         * (non-Javadoc)
277
         * @see org.gvsig.fmap.dal.coverage.store.props.HistogramComputer#refreshHistogram()
278
         */
279
        public void refreshHistogram() {
280
                refresh = true;
281
        }
282
        
283
        protected void setBufferHistogram(BufferHistogram bh) {
284
                if(bh instanceof BufferHistogramImpl)
285
                        this.histogram = (BufferHistogramImpl)bh;
286
        }
287
        
288
        /**
289
         * Joins the this histogram object with the parameter and
290
         * returns a new Histogram object.
291
         * @param stats
292
         * @return
293
         * @throws InterruptedException 
294
         * @throws HistogramException 
295
         */
296
        public static HistogramComputer union(RasterProvider prov, ArrayList<RasterProvider> list) throws HistogramException, InterruptedException {
297
                SimpleProviderHistogramComputer newHistogramComputer = new SimpleProviderHistogramComputer(prov);
298
                for (int i = 0; i < list.size(); i++) {
299
                        HistogramComputer hc = list.get(0).getHistogramComputer();
300
                        try {
301
                                BufferHistogram bh = hc.getBufferHistogram();
302
                                if(newHistogramComputer.histogram == null) {
303
                                        newHistogramComputer.setBufferHistogram(bh);
304
                                } else {
305
                                        newHistogramComputer.histogram.union(bh);
306
                                }
307
                        } catch (ProcessInterruptedException e) {
308
                                throw new InterruptedException();
309
                        }
310
                }
311
                return newHistogramComputer;
312
        }
313

    
314
        public String getLog() {
315
                return null;
316
        }
317

    
318
        public boolean isCancelable() {
319
                return true;
320
        }
321

    
322
        public boolean isPausable() {
323
                return false;
324
        }
325

    
326
        public void setPercent(int value) {
327
                
328
        }
329
}