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 @ 1676

History | View | Annotate | Download (11.2 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
        private double                  scale     = 1;
65
        
66
        /**
67
         * Constructor
68
         * @param dataset
69
         */
70
        public SimpleProviderHistogramComputer(RasterProvider provider) {
71
                this.provider = provider;
72
        }
73
        
74
        public void setScaleHistogram(double scale) {
75
                this.scale = scale;
76
        }
77

    
78
        /**
79
         * Obtiene el minimo valor de las estadisticas de un histograma.
80
         * @return double
81
         */
82
        public double getMinimum() {
83
                return provider.getStatistics().getMinimun();
84
        }
85

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

    
110
                                try {
111
                                        histogram = (BufferHistogramImpl) provider.loadObjectFromRmf(BufferHistogram.class, histogram);
112
                                        if (histogram != null)
113
                                                return histogram;
114
                                } catch (RmfSerializerException e) {
115
                                        //No carga desde rmf. No afecta a la funcionalidad
116
                                }
117

    
118
                                if(task.getEvent() != null)
119
                                        task.manageEvent(task.getEvent());
120

    
121
                                histogram = new BufferHistogramImpl(provider.getBandCount(), 
122
                                                provider.getStatistics().getMin(), 
123
                                                provider.getStatistics().getMax(), 
124
                                                provider.getDataType()[0]);
125

    
126
                                try {
127
                                        histogram = (BufferHistogramImpl)getHistogramByDataType();
128
                                } catch (FileNotOpenException e) {
129
                                        throw new HistogramException("", e);
130
                                } catch (RasterDriverException e) {
131
                                        throw new HistogramException("", e);
132
                                } catch (Exception e) {
133
                                        logger.info("Error calculando el histograma", e);
134
                                }
135

    
136
                                try {
137
                                        provider.saveObjectToRmf(BufferHistogram.class, histogram);
138
                                } catch (RmfSerializerException e) {
139
                                        //No salva a rmf. No afecta a la funcionalidad
140
                                }
141
                        }
142
                        return histogram;
143

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

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

    
200
                if(provider.getNoDataValue().isDefined())
201
                        histogram.setNoDataValue(provider.getNoDataValue());
202
                for (int block = 0; block < provider.getHeight(); block += h) {
203
                        Object buf = null;
204
                        try {
205
                                buf = provider.readBlock(block, h, scale);
206
                        } catch (InvalidSetViewException e) {
207
                                // La vista se asigna autom?ticamente
208
                        }
209

    
210
                        int hB = h;
211
                        if ((block + hB) > provider.getHeight())
212
                                hB = Math.abs(((int)provider.getHeight()) - block);
213
                        
214
                        hB *= scale;
215

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

    
265
        /**
266
         * Pone a cero el porcentaje de progreso del proceso de calculo de histograma
267
         */
268
        public void resetPercent() {
269
                percent = 0;
270
        }
271

    
272
        /**
273
         * Obtiene el porcentaje de progreso del proceso de calculo de histograma
274
         * @return porcentaje de progreso
275
         */
276
        public int getPercent() {
277
                return percent;
278
        }
279

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

    
319
        public String getLog() {
320
                return null;
321
        }
322

    
323
        public boolean isCancelable() {
324
                return true;
325
        }
326

    
327
        public boolean isPausable() {
328
                return false;
329
        }
330

    
331
        public void setPercent(int value) {
332
                
333
        }
334
}