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 @ 8703
History | View | Annotate | Download (11.2 KB)
1 | 2443 | nbrodin | /* 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.List; |
||
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, List<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 | } |