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

History | View | Annotate | Download (10.8 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

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

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

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

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

    
111
                                        if(task.getEvent() != null)
112
                                                task.manageEvent(task.getEvent());
113

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

    
119
                                        try {
120
                                                histogram = (BufferHistogramImpl)getHistogramByDataType();
121
                                        } catch (FileNotOpenException e) {
122
                                                throw new HistogramException("");
123
                                        } catch (RasterDriverException e) {
124
                                                throw new HistogramException("");
125
                                        }
126

    
127
                                        try {
128
                                                provider.saveObjectToRmf(BufferHistogram.class, histogram);
129
                                        } catch (RmfSerializerException e) {
130
                                                //No salva a rmf. No afecta a la funcionalidad
131
                                        }
132
                                }
133
                                return histogram;
134

    
135
                        }
136
                } catch (InvalidSetViewException e) {
137
                        //La vista se selecciona autom?ticamente no deber?a darse esta excepci?n
138
                }
139
                return null;
140
        }
141
        
142
        /**
143
         * Gets an array of data from a buffer 
144
         * @param type
145
         * @param buf
146
         * @return
147
         */
148
        private void loadHistogramFromBuffer(Buffer buf) {
149
                switch (buf.getDataType()) {
150
                case Buffer.TYPE_BYTE:
151
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++)
152
                                for (int col = 0; col < buf.getWidth(); col++)
153
                                        for (int row = 0; row < buf.getHeight(); row++)
154
                                                histogram.incrementPxValue(iBand, (double) buf.getElemByte(row, col, iBand));
155
                        break;
156
                case Buffer.TYPE_SHORT:
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.getElemShort(row, col, iBand));
161
                        break;
162
                case Buffer.TYPE_FLOAT:
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.getElemFloat(row, col, iBand));
167
                        break;
168
                case Buffer.TYPE_DOUBLE:
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.getElemDouble(row, col, iBand));
173
                        break;
174
                case Buffer.TYPE_INT:
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.getElemInt(row, col, iBand));
179
                        break;
180
                }
181
        }
182

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

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

    
204
                        int hB = h;
205
                        if ((block + hB) > provider.getHeight())
206
                                hB = Math.abs(((int)provider.getHeight()) - block);
207

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

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

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

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