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 / DataStoreStatistics.java @ 162
History | View | Annotate | Download (13.7 KB)
1 | 77 | 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 org.gvsig.fmap.dal.coverage.RasterLibrary; |
||
25 | import org.gvsig.fmap.dal.coverage.dataset.Buffer; |
||
26 | import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException; |
||
27 | import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException; |
||
28 | 90 | nbrodin | import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException; |
29 | 77 | nbrodin | import org.gvsig.fmap.dal.coverage.exception.RasterDriverException; |
30 | import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException; |
||
31 | 94 | nbrodin | import org.gvsig.raster.impl.process.RasterTask; |
32 | import org.gvsig.raster.impl.process.RasterTaskQueue; |
||
33 | 81 | nbrodin | import org.gvsig.raster.impl.provider.RasterProvider; |
34 | 77 | nbrodin | /**
|
35 | * Statistics for a raster provider.
|
||
36 | *
|
||
37 | * @author Nacho Brodin (nachobrodin@gmail.com)
|
||
38 | */
|
||
39 | 162 | nbrodin | public class DataStoreStatistics extends AbstractStatistics { |
40 | 77 | nbrodin | private RasterProvider provider = null; |
41 | private int bandCount = 0; |
||
42 | private int percent = 0; |
||
43 | private boolean forceToRecalc = false; |
||
44 | |||
45 | /**
|
||
46 | * Constructor. Asigna el fichero asociado.
|
||
47 | */
|
||
48 | 162 | nbrodin | public DataStoreStatistics(RasterProvider prov) {
|
49 | 77 | nbrodin | this.provider = prov;
|
50 | if(provider != null) |
||
51 | bandCount = provider.getBandCount(); |
||
52 | } |
||
53 | |||
54 | /**
|
||
55 | * Obtiene el dataset asociado
|
||
56 | * @return
|
||
57 | */
|
||
58 | public RasterProvider getDataProvider() {
|
||
59 | return provider;
|
||
60 | } |
||
61 | |||
62 | /**
|
||
63 | * Asigna el valor m?ximo del grid
|
||
64 | * @return Valor m?ximo
|
||
65 | */
|
||
66 | public void setMax(double[] max) { |
||
67 | this.max = max;
|
||
68 | } |
||
69 | |||
70 | /**
|
||
71 | * Asigna el valor del segundo m?ximo
|
||
72 | * @return Valor del segundo m?ximo
|
||
73 | */
|
||
74 | public void setSecondMax(double[] smax) { |
||
75 | this.secondMax = smax;
|
||
76 | } |
||
77 | |||
78 | /**
|
||
79 | * Asigna el valor m?ximo del grid
|
||
80 | * @return Valor m?ximo
|
||
81 | */
|
||
82 | public void setMaxRGB(double[] max) { |
||
83 | this.maxByteUnsigned = max;
|
||
84 | } |
||
85 | |||
86 | /**
|
||
87 | * Asigna el valor del segundo m?ximo
|
||
88 | * @return Valor del segundo m?ximo
|
||
89 | */
|
||
90 | public void setSecondMaxRGB(double[] smax) { |
||
91 | this.secondMaxByteUnsigned = smax;
|
||
92 | } |
||
93 | |||
94 | /**
|
||
95 | * Asigna el valor m?dio del grid
|
||
96 | * @return Valor medio
|
||
97 | */
|
||
98 | public void setMean(double[] mean) { |
||
99 | this.mean = mean;
|
||
100 | } |
||
101 | |||
102 | /**
|
||
103 | * Asigna el valor m?ximo del grid
|
||
104 | * @return Valor m?nimo
|
||
105 | */
|
||
106 | public void setMin(double[] min) { |
||
107 | this.min = min;
|
||
108 | } |
||
109 | |||
110 | /**
|
||
111 | * Asigna el valor del segundo m?nimo
|
||
112 | * @return Valor del segundo m?nimo
|
||
113 | */
|
||
114 | public void setSecondMin(double[] smin) { |
||
115 | this.secondMin = smin;
|
||
116 | } |
||
117 | |||
118 | /**
|
||
119 | * Asigna el valor m?ximo del grid
|
||
120 | * @return Valor m?nimo
|
||
121 | */
|
||
122 | public void setMinRGB(double[] min) { |
||
123 | this.minByteUnsigned = min;
|
||
124 | } |
||
125 | |||
126 | /**
|
||
127 | * Asigna el valor del segundo m?nimo
|
||
128 | * @return Valor del segundo m?nimo
|
||
129 | */
|
||
130 | public void setSecondMinRGB(double[] smin) { |
||
131 | this.secondMinByteUnsigned = smin;
|
||
132 | } |
||
133 | |||
134 | /**
|
||
135 | * Asigna la varianza
|
||
136 | * @return Varianza
|
||
137 | */
|
||
138 | public void setVariance(double[] variance) { |
||
139 | this.variance = variance;
|
||
140 | } |
||
141 | |||
142 | /*
|
||
143 | * (non-Javadoc)
|
||
144 | * @see org.gvsig.raster.hierarchy.IStatistics#getMin()
|
||
145 | */
|
||
146 | public double[] getMin() { |
||
147 | return min;
|
||
148 | } |
||
149 | |||
150 | /*
|
||
151 | * (non-Javadoc)
|
||
152 | * @see org.gvsig.raster.hierarchy.IStatistics#getMax()
|
||
153 | */
|
||
154 | public double[] getMax() { |
||
155 | return max;
|
||
156 | } |
||
157 | |||
158 | /*
|
||
159 | * (non-Javadoc)
|
||
160 | * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMax()
|
||
161 | */
|
||
162 | public double[] getSecondMax() { |
||
163 | return secondMax;
|
||
164 | } |
||
165 | |||
166 | /*
|
||
167 | * (non-Javadoc)
|
||
168 | * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMin()
|
||
169 | */
|
||
170 | public double[] getSecondMin() { |
||
171 | return secondMin;
|
||
172 | } |
||
173 | |||
174 | /*
|
||
175 | * (non-Javadoc)
|
||
176 | * @see org.gvsig.raster.hierarchy.IStatistics#getMinRGB()
|
||
177 | */
|
||
178 | public double[] getMinByteUnsigned() { |
||
179 | return minByteUnsigned;
|
||
180 | } |
||
181 | |||
182 | /*
|
||
183 | * (non-Javadoc)
|
||
184 | * @see org.gvsig.raster.hierarchy.IStatistics#getMaxRGB()
|
||
185 | */
|
||
186 | public double[] getMaxByteUnsigned() { |
||
187 | return maxByteUnsigned;
|
||
188 | } |
||
189 | |||
190 | /*
|
||
191 | * (non-Javadoc)
|
||
192 | * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMaxRGB()
|
||
193 | */
|
||
194 | public double[] getSecondMaxByteUnsigned() { |
||
195 | return secondMaxByteUnsigned;
|
||
196 | } |
||
197 | |||
198 | /*
|
||
199 | * (non-Javadoc)
|
||
200 | * @see org.gvsig.raster.hierarchy.IStatistics#getSecondMinRGB()
|
||
201 | */
|
||
202 | public double[] getSecondMinByteUnsigned() { |
||
203 | return secondMinByteUnsigned;
|
||
204 | } |
||
205 | |||
206 | /*
|
||
207 | * (non-Javadoc)
|
||
208 | * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMaximun()
|
||
209 | */
|
||
210 | public double getMaximun() { |
||
211 | double m = Double.NEGATIVE_INFINITY; |
||
212 | for (int i = 0; i < max.length; i++) |
||
213 | m = Math.max(m, max[i]);
|
||
214 | return m;
|
||
215 | } |
||
216 | |||
217 | /*
|
||
218 | * (non-Javadoc)
|
||
219 | * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMinimun()
|
||
220 | */
|
||
221 | public double getMinimun() { |
||
222 | double m = Double.MAX_VALUE; |
||
223 | for (int i = 0; i < min.length; i++) |
||
224 | m = Math.min(m, min[i]);
|
||
225 | return m;
|
||
226 | } |
||
227 | |||
228 | /*
|
||
229 | * (non-Javadoc)
|
||
230 | * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMaximunByteUnsigned()
|
||
231 | */
|
||
232 | public double getMaximunByteUnsigned() { |
||
233 | double m = Double.NEGATIVE_INFINITY; |
||
234 | for (int i = 0; i < maxByteUnsigned.length; i++) |
||
235 | m = Math.max(m, maxByteUnsigned[i]);
|
||
236 | return m;
|
||
237 | } |
||
238 | |||
239 | /*
|
||
240 | * (non-Javadoc)
|
||
241 | * @see org.gvsig.fmap.dal.coverage.dataset.Statistics#getMinimunByteUnsigned()
|
||
242 | */
|
||
243 | public double getMinimunByteUnsigned() { |
||
244 | double m = Double.MAX_VALUE; |
||
245 | for (int i = 0; i < minByteUnsigned.length; i++) |
||
246 | m = Math.min(m, minByteUnsigned[i]);
|
||
247 | return m;
|
||
248 | } |
||
249 | |||
250 | /*
|
||
251 | * (non-Javadoc)
|
||
252 | * @see org.gvsig.raster.hierarchy.IStatistics#getMean()
|
||
253 | */
|
||
254 | public double[] getMean() { |
||
255 | return mean;
|
||
256 | } |
||
257 | |||
258 | /*
|
||
259 | * (non-Javadoc)
|
||
260 | * @see org.gvsig.raster.hierarchy.IStatistics#getVariance()
|
||
261 | */
|
||
262 | public double[] getVariance() { |
||
263 | return variance;
|
||
264 | } |
||
265 | |||
266 | /*
|
||
267 | * (non-Javadoc)
|
||
268 | * @see org.gvsig.raster.hierarchy.IStatistics#getBandCount()
|
||
269 | */
|
||
270 | public int getBandCount(){ |
||
271 | return this.bandCount; |
||
272 | } |
||
273 | |||
274 | /**
|
||
275 | * Asigna el n?mero de bandas
|
||
276 | * @param bandCount
|
||
277 | */
|
||
278 | public void setBandCount(int bandCount) { |
||
279 | this.bandCount = bandCount;
|
||
280 | } |
||
281 | |||
282 | /*
|
||
283 | * (non-Javadoc)
|
||
284 | * @see org.gvsig.raster.hierarchy.IStatistics#calcFullStatistics()
|
||
285 | */
|
||
286 | 123 | nbrodin | public void calculate() throws FileNotOpenException, RasterDriverException, ProcessInterruptedException { |
287 | 77 | nbrodin | if (provider == null) |
288 | return;
|
||
289 | |||
290 | RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
|
||
291 | percent = 0;
|
||
292 | |||
293 | // Si no se fuerza su calculo, intentamos ver si estan calculadas y sino
|
||
294 | // las intentamos cargar del RMF
|
||
295 | if (!forceToRecalc) {
|
||
296 | if (!isCalculated()) {
|
||
297 | try {
|
||
298 | 162 | nbrodin | provider.loadObjectFromRmf(DataStoreStatistics.class, this);
|
299 | 77 | nbrodin | } catch (RmfSerializerException e) {
|
300 | // Si no se puede cargar del RMF, recalcularemos las estadisticas.
|
||
301 | } |
||
302 | } |
||
303 | if (isCalculated())
|
||
304 | return;
|
||
305 | } |
||
306 | |||
307 | bandCount = provider.getBandCount(); |
||
308 | max = new double[bandCount]; |
||
309 | min = new double[bandCount]; |
||
310 | secondMax = new double[bandCount]; |
||
311 | secondMin = new double[bandCount]; |
||
312 | maxByteUnsigned = new double[bandCount]; |
||
313 | minByteUnsigned = new double[bandCount]; |
||
314 | secondMaxByteUnsigned = new double[bandCount]; |
||
315 | secondMinByteUnsigned = new double[bandCount]; |
||
316 | mean = new double[bandCount]; |
||
317 | variance = new double[bandCount]; |
||
318 | |||
319 | int blockHeight = RasterLibrary.blockHeight;
|
||
320 | long[] iValues = new long[bandCount]; |
||
321 | boolean[] initializedBand = new boolean[bandCount]; |
||
322 | int[] type = new int[bandCount]; |
||
323 | byte[][][] b = null; |
||
324 | short[][][] s = null; |
||
325 | int[][][] i = null; |
||
326 | float[][][] f = null; |
||
327 | double[][][] d = null; |
||
328 | double z = 0; |
||
329 | double rgb = 0; |
||
330 | |||
331 | for (int iBand = 0; iBand < bandCount; iBand++) { |
||
332 | max[iBand] = Double.NEGATIVE_INFINITY;
|
||
333 | min[iBand] = Double.POSITIVE_INFINITY;
|
||
334 | secondMax[iBand] = Double.NEGATIVE_INFINITY;
|
||
335 | secondMin[iBand] = Double.POSITIVE_INFINITY;
|
||
336 | maxByteUnsigned[iBand] = 0;
|
||
337 | minByteUnsigned[iBand] = 255;
|
||
338 | secondMaxByteUnsigned[iBand] = 0;
|
||
339 | secondMinByteUnsigned[iBand] = 255;
|
||
340 | initializedBand[iBand] = false;
|
||
341 | type[iBand] = provider.getDataType()[iBand]; |
||
342 | } |
||
343 | |||
344 | for (int height = 0; height < provider.getHeight(); height += blockHeight) { |
||
345 | try {
|
||
346 | Object buf = provider.readBlock(height, blockHeight);
|
||
347 | switch (type[0]) { |
||
348 | case Buffer.TYPE_BYTE: b = (byte[][][]) buf; break; |
||
349 | case Buffer.TYPE_SHORT: s = (short[][][]) buf; break; |
||
350 | case Buffer.TYPE_FLOAT: f = (float[][][]) buf; break; |
||
351 | case Buffer.TYPE_DOUBLE: d = (double[][][]) buf; break; |
||
352 | case Buffer.TYPE_INT: i = (int[][][]) buf; break; |
||
353 | } |
||
354 | } catch (InvalidSetViewException e) {
|
||
355 | // La vista se asigna autom?ticamente
|
||
356 | return;
|
||
357 | } |
||
358 | |||
359 | int hB = blockHeight;
|
||
360 | if ((height + hB) > provider.getHeight())
|
||
361 | hB = ((int)provider.getHeight()) - height;
|
||
362 | for (int iBand = 0; iBand < bandCount; iBand++) { |
||
363 | for (int col = 0; col < provider.getWidth(); col++) { |
||
364 | for (int row = 0; row < hB; row++) { |
||
365 | z = (b != null) ? b[iBand][row][col] :
|
||
366 | (s != null) ? s[iBand][row][col] :
|
||
367 | (d != null) ? d[iBand][row][col] :
|
||
368 | (f != null) ? f[iBand][row][col] :
|
||
369 | (i != null) ? i[iBand][row][col] :
|
||
370 | 0;
|
||
371 | |||
372 | if (provider.isNoDataEnabled() && (z == provider.getNoDataValue()))
|
||
373 | continue;
|
||
374 | |||
375 | if (Double.isNaN(z)) |
||
376 | continue;
|
||
377 | |||
378 | rgb = 0;
|
||
379 | if(b != null) { |
||
380 | rgb = ((byte) z) & 0xff; |
||
381 | mean[iBand] += rgb; |
||
382 | variance[iBand] += rgb * rgb; |
||
383 | } else {
|
||
384 | //rgb = (b != null) ? ((byte) z) & 0xff : 0;
|
||
385 | mean[iBand] += z; |
||
386 | variance[iBand] += z * z; |
||
387 | } |
||
388 | iValues[iBand]++; |
||
389 | |||
390 | if (!initializedBand[iBand]) {
|
||
391 | secondMin[iBand] = min[iBand]; |
||
392 | secondMax[iBand] = max[iBand]; |
||
393 | min[iBand] = z; |
||
394 | max[iBand] = z; |
||
395 | secondMinByteUnsigned[iBand] = minByteUnsigned[iBand]; |
||
396 | secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand]; |
||
397 | minByteUnsigned[iBand] = rgb; |
||
398 | maxByteUnsigned[iBand] = rgb; |
||
399 | initializedBand[iBand] = true;
|
||
400 | continue;
|
||
401 | } |
||
402 | |||
403 | if (z < secondMin[iBand]) {
|
||
404 | if (z < min[iBand]) {
|
||
405 | secondMin[iBand] = min[iBand]; |
||
406 | min[iBand] = z; |
||
407 | } else {
|
||
408 | if (z > min[iBand])
|
||
409 | secondMin[iBand] = z; |
||
410 | } |
||
411 | } |
||
412 | |||
413 | if (z > secondMax[iBand]) {
|
||
414 | if (z > max[iBand]) {
|
||
415 | secondMax[iBand] = max[iBand]; |
||
416 | max[iBand] = z; |
||
417 | } else {
|
||
418 | if (z < max[iBand])
|
||
419 | secondMax[iBand] = z; |
||
420 | } |
||
421 | } |
||
422 | |||
423 | if (rgb < secondMinByteUnsigned[iBand]) {
|
||
424 | if (rgb < minByteUnsigned[iBand]) {
|
||
425 | secondMinByteUnsigned[iBand] = minByteUnsigned[iBand]; |
||
426 | minByteUnsigned[iBand] = rgb; |
||
427 | } else {
|
||
428 | if (rgb > minByteUnsigned[iBand])
|
||
429 | secondMinByteUnsigned[iBand] = rgb; |
||
430 | } |
||
431 | } |
||
432 | |||
433 | if (rgb > secondMaxByteUnsigned[iBand]) {
|
||
434 | if (rgb > maxByteUnsigned[iBand]) {
|
||
435 | secondMaxByteUnsigned[iBand] = maxByteUnsigned[iBand]; |
||
436 | maxByteUnsigned[iBand] = rgb; |
||
437 | } else {
|
||
438 | if (rgb < maxByteUnsigned[iBand])
|
||
439 | secondMaxByteUnsigned[iBand] = rgb; |
||
440 | } |
||
441 | } |
||
442 | } |
||
443 | } |
||
444 | if (task.getEvent() != null) |
||
445 | task.manageEvent(task.getEvent()); |
||
446 | } |
||
447 | percent = ((height * 100) / (int)provider.getHeight()); |
||
448 | } |
||
449 | percent = 100;
|
||
450 | |||
451 | for (int iBand = 0; iBand < bandCount; iBand++) { |
||
452 | if (iValues[iBand] > 0) { |
||
453 | mean[iBand] = mean[iBand] / (double) iValues[iBand];
|
||
454 | variance[iBand] = variance[iBand] / (double) iValues[iBand] - mean[iBand] * mean[iBand];
|
||
455 | } |
||
456 | } |
||
457 | |||
458 | calculated = true;
|
||
459 | forceToRecalc = false;
|
||
460 | try {
|
||
461 | 162 | nbrodin | provider.saveObjectToRmf(DataStoreStatistics.class, this);
|
462 | 77 | nbrodin | } catch (RmfSerializerException e) {
|
463 | // No salva a rmf
|
||
464 | } |
||
465 | } |
||
466 | |||
467 | /*
|
||
468 | * (non-Javadoc)
|
||
469 | * @see org.gvsig.raster.hierarchy.IStatistics#isCalculated()
|
||
470 | */
|
||
471 | public boolean isCalculated() { |
||
472 | return calculated;
|
||
473 | } |
||
474 | |||
475 | /**
|
||
476 | * Asigna el flag de estad?sticas calculadas.
|
||
477 | * @param calc
|
||
478 | */
|
||
479 | public void setCalculated(boolean calc) { |
||
480 | calculated = calc; |
||
481 | } |
||
482 | |||
483 | /*
|
||
484 | * (non-Javadoc)
|
||
485 | * @see org.gvsig.raster.hierarchy.IStatistics#setTailTrimValue(double, java.lang.Object)
|
||
486 | */
|
||
487 | public void setTailTrimValue(double percent, Object valueByBand){ |
||
488 | tailTrim.put(percent + "", valueByBand);
|
||
489 | for (int i = 0; i < tailTrimValues.size(); i++) { |
||
490 | if(tailTrimValues.get(i).equals(percent + "")) { |
||
491 | tailTrimValues.set(i, percent + "");
|
||
492 | return;
|
||
493 | } |
||
494 | } |
||
495 | tailTrimValues.add(percent + "");
|
||
496 | } |
||
497 | |||
498 | /*
|
||
499 | * (non-Javadoc)
|
||
500 | * @see org.gvsig.raster.hierarchy.IStatistics#getTailTrimValue(double)
|
||
501 | */
|
||
502 | public Object getTailTrimValue(double percent){ |
||
503 | return tailTrim.get(percent + ""); |
||
504 | } |
||
505 | |||
506 | /*
|
||
507 | * (non-Javadoc)
|
||
508 | * @see org.gvsig.raster.shared.IStatistics#getTailTrimValue(int)
|
||
509 | */
|
||
510 | public Object[] getTailTrimValue(int pos) { |
||
511 | return new Object[] { Double.valueOf(Double.parseDouble(tailTrimValues.get(pos) + "")), tailTrim.get(tailTrimValues.get(pos)) }; |
||
512 | } |
||
513 | |||
514 | /*
|
||
515 | * (non-Javadoc)
|
||
516 | * @see org.gvsig.raster.shared.IStatistics#getTailTrimCount()
|
||
517 | */
|
||
518 | public int getTailTrimCount() { |
||
519 | return tailTrimValues.size();
|
||
520 | } |
||
521 | |||
522 | /**
|
||
523 | * Pone a cero el porcentaje de progreso del proceso de calculo de histograma
|
||
524 | */
|
||
525 | public void resetPercent() { |
||
526 | percent = 0;
|
||
527 | } |
||
528 | |||
529 | /**
|
||
530 | * Obtiene el porcentaje de progreso del proceso de calculo de histograma
|
||
531 | * @return porcentaje de progreso
|
||
532 | */
|
||
533 | public int getPercent() { |
||
534 | return percent;
|
||
535 | } |
||
536 | |||
537 | /**
|
||
538 | * Cuando se llama a este m?todo fuerza que la siguiente petici?n de estad?sticas
|
||
539 | * no sea le?da de RMF y sean recalculadas por completo.
|
||
540 | * @param forceToRecalc
|
||
541 | */
|
||
542 | public void forceToRecalc() { |
||
543 | this.forceToRecalc = true; |
||
544 | } |
||
545 | 123 | nbrodin | |
546 | 77 | nbrodin | } |