svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / RasterBuffer.java @ 20759
History | View | Annotate | Download (19.7 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
|
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU General Public License
|
7 |
* as published by the Free Software Foundation; either version 2
|
8 |
* of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This program is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
* GNU General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU General Public License
|
16 |
* along with this program; if not, write to the Free Software
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
18 |
*/
|
19 |
package org.gvsig.raster.buffer; |
20 |
|
21 |
import java.io.FileNotFoundException; |
22 |
|
23 |
import org.gvsig.raster.RasterLibrary; |
24 |
import org.gvsig.raster.buffer.cache.RasterCache; |
25 |
import org.gvsig.raster.buffer.cache.RasterReadOnlyBuffer; |
26 |
import org.gvsig.raster.dataset.IBuffer; |
27 |
import org.gvsig.raster.dataset.IRasterDataSource; |
28 |
import org.gvsig.raster.dataset.NotSupportedExtensionException; |
29 |
import org.gvsig.raster.dataset.io.RasterDriverException; |
30 |
import org.gvsig.raster.datastruct.Histogram; |
31 |
import org.gvsig.raster.process.RasterTask; |
32 |
import org.gvsig.raster.process.RasterTaskQueue; |
33 |
import org.gvsig.raster.util.RasterUtilities; |
34 |
|
35 |
/**
|
36 |
* Rectangulo de pixeles. Para cada tipo de datos java hay un buffer distinto donde cada elemento es
|
37 |
* accedido de la siguiente forma: [banda][fila][columna]
|
38 |
* m[1][2][0] = cte;-> Sustituye el elemento de la fila 2 de la banda 1 columna 0
|
39 |
* m[1][0] = array; -> Sustituye la fila 0 de la banda 1
|
40 |
* m[0] = matriz cuadrada; -> Sustituye la banda entera.
|
41 |
*
|
42 |
*/
|
43 |
public abstract class RasterBuffer implements IBuffer { |
44 |
public static final int INTERPOLATION_PROCESS = 0; |
45 |
public static final int HISTOGRAM_PROCESS = 1; |
46 |
|
47 |
protected boolean[] cancel = new boolean[1]; |
48 |
|
49 |
public double noDataValue = -99999; |
50 |
|
51 |
protected int progressHistogram = 0; |
52 |
protected int progressInterpolation = 0; |
53 |
protected boolean canceled = false; |
54 |
|
55 |
protected int width; |
56 |
protected int height; |
57 |
protected int nBands; |
58 |
protected int dataType; |
59 |
|
60 |
/**
|
61 |
* Variable est?tica que si est? a false desactiva el uso de cach?. Puede ser usada por un cliente
|
62 |
* para cargar siempre los datos en memoria. independientemente de su tama?o.
|
63 |
*/
|
64 |
public static boolean cacheOn = true; |
65 |
/**
|
66 |
* Fuerza la carga de los datos en cach? independientemente de su tama?o. Su
|
67 |
* uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
|
68 |
* es siempre false.
|
69 |
*/
|
70 |
public static boolean forceToLoadInCache = false; |
71 |
/**
|
72 |
* Fuerza la carga de los datos en cach? de solo lectura independientemente de su tama?o. Su
|
73 |
* uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
|
74 |
* es siempre false.
|
75 |
*/
|
76 |
public static boolean forceToLoadInReadOnlyCache = false; |
77 |
/**
|
78 |
* Valor con el que se rellena una banda no valida del buffer. Una banda no valida es la que
|
79 |
* no tiene datos asignados y tampoco puede ser null. Todas las bandas no validas de un buffer
|
80 |
* apuntan por referencia a la misma banda.
|
81 |
*/
|
82 |
protected double notValidValue = 0D; |
83 |
|
84 |
private BufferInterpolation interp = null; |
85 |
|
86 |
/**
|
87 |
* Proceso del cual se devuelve el porcentaje cuando este es solicitado
|
88 |
*/
|
89 |
private int process = HISTOGRAM_PROCESS; |
90 |
|
91 |
/**
|
92 |
* Genera instancias del buffer de datos adecuado al tama?o del raster. Si no hay muchos datos
|
93 |
* (menos de cacheMemorySize) crear? un buffer en memoria. Si hay m?s de esta cantidad
|
94 |
* entonces crearemos un buffer cacheado (RasterCache). A partir de la cantidad se?alada
|
95 |
* por multicacheMemorySize haremos un buffer cacheado donde cada p?gina no ocupa todo
|
96 |
* el ancho del raster ya que este ser? muy grande. La gesti?n de una cache donde cada
|
97 |
* pagina ha de partir una l?nea lleva una complejidad a?adida.
|
98 |
*
|
99 |
* @param dataType Tipo de dato
|
100 |
* @param width Ancho
|
101 |
* @param height Alto
|
102 |
* @param bandNr Banda
|
103 |
* @param flag En caso de buffers de memoria este flag a true significa que se reserva la memoria
|
104 |
* para el buffer de forma normal y si est? a false no se reserva por lo que la reserva deber? ser
|
105 |
* posterior.
|
106 |
* @return Objeto RasterBuffer
|
107 |
* @throws RasterDriverException
|
108 |
* @throws NotSupportedExtensionException
|
109 |
* @throws FileNotFoundException
|
110 |
*/
|
111 |
public static RasterBuffer getBuffer(int dataType, int width, int height, int bandNr, boolean malloc) |
112 |
/*throws FileNotFoundException, NotSupportedExtensionException, RasterDriverException*/{
|
113 |
//Opci?n de cachear siempre activada (Solo DEBUG)
|
114 |
if(forceToLoadInCache)
|
115 |
return new RasterCache(dataType, width, height, bandNr); |
116 |
if(forceToLoadInReadOnlyCache){
|
117 |
return new RasterReadOnlyBuffer(dataType, width, height, bandNr); |
118 |
} |
119 |
|
120 |
if(cacheOn){
|
121 |
long size = (RasterUtilities.getBytesFromRasterBufType(dataType) * width * height * bandNr) / 1024; |
122 |
long ms1 = RasterLibrary.cacheSize * 1024; |
123 |
if(size <= ms1)
|
124 |
return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc); |
125 |
else
|
126 |
return new RasterCache(dataType, width, height, bandNr); |
127 |
}else
|
128 |
return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc); |
129 |
} |
130 |
|
131 |
/**
|
132 |
* Genera una instancia del buffer de solo lectura. Este buffer consta de una cache y unos apuntadores
|
133 |
* a las p?ginas en disco. Cuando se accede a los datos se carga en memoria la p?gina pedida.
|
134 |
*
|
135 |
* @param dataType Tipo de dato
|
136 |
* @param width Ancho
|
137 |
* @param height Alto
|
138 |
* @param bandNr Banda
|
139 |
*/
|
140 |
public static RasterBuffer getReadOnlyBuffer(int dataType, int width, int height, int bandNr) { |
141 |
return new RasterReadOnlyBuffer(dataType, width, height, bandNr); |
142 |
} |
143 |
|
144 |
/**
|
145 |
* Genera una instancia del buffer de solo lectura. Este buffer consta de una cache y unos apuntadores
|
146 |
* a las p?ginas en disco. Cuando se accede a los datos se carga en memoria la p?gina pedida.
|
147 |
*
|
148 |
* @param dataType Tipo de dato
|
149 |
* @param width Ancho
|
150 |
* @param height Alto
|
151 |
* @param bandNr Banda
|
152 |
* @param flag En caso de buffers de memoria este flag a true significa que se reserva la memoria
|
153 |
* para el buffer de forma normal y si est? a false no se reserva por lo que la reserva deber? ser
|
154 |
* posterior.
|
155 |
*/
|
156 |
public static RasterBuffer getMemoryBuffer(int dataType, int width, int height, int bandNr, boolean malloc) { |
157 |
return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc); |
158 |
} |
159 |
/**
|
160 |
* Devuelve true si el tama?o del dataset es menor que el de la cach? y false
|
161 |
* si no lo es.
|
162 |
* @param datasource Fuente de datos
|
163 |
* @return true si podemos cargar en memoria el raster
|
164 |
*/
|
165 |
public static boolean loadInMemory(IRasterDataSource datasource) { |
166 |
return (datasource.getFileSize() < (RasterLibrary.cacheSize * 1048576)); |
167 |
} |
168 |
|
169 |
/**
|
170 |
* Dadas unas coordenadas pixel y un n?mero de bandas, esta funci?n comprueba si
|
171 |
* el tama?o de ventana que va a generarse supera el tama?o de la cach?
|
172 |
* @param coords Coordenadas pixel del raster
|
173 |
* @param bands N?mero de bandas
|
174 |
* @param ds
|
175 |
* @return true si la ventana supera el tama?o de la cach? o false si no lo supera.
|
176 |
*/
|
177 |
public static boolean isBufferTooBig(double[] coords, int bands) { |
178 |
int w = (int)Math.abs(coords[2] - coords[0]); |
179 |
int h = (int)Math.abs(coords[3] - coords[1]); |
180 |
|
181 |
long windowSize = w * h * bands;
|
182 |
return (windowSize > (RasterLibrary.cacheSize * 1048576)); |
183 |
} |
184 |
|
185 |
/**
|
186 |
* Reserva de memoria para el rasterbuf
|
187 |
* @param dataType Tipo de dato
|
188 |
* @param width Ancho
|
189 |
* @param height Alto
|
190 |
* @param bandNr Numero de bandas
|
191 |
* @param orig
|
192 |
*/
|
193 |
public abstract void malloc(int dataType, int width, int height, int bandNr); |
194 |
|
195 |
/*
|
196 |
* (non-Javadoc)
|
197 |
* @see org.gvsig.fmap.driver.IBuffer#getWidth()
|
198 |
*/
|
199 |
public int getWidth() { |
200 |
return width;
|
201 |
} |
202 |
|
203 |
/*
|
204 |
* (non-Javadoc)
|
205 |
* @see org.gvsig.fmap.driver.IBuffer#getHeight()
|
206 |
*/
|
207 |
public int getHeight() { |
208 |
return height;
|
209 |
} |
210 |
|
211 |
/*
|
212 |
* (non-Javadoc)
|
213 |
* @see org.gvsig.fmap.driver.IBuffer#getBandCount()
|
214 |
*/
|
215 |
public int getBandCount() { |
216 |
return nBands;
|
217 |
} |
218 |
|
219 |
/**
|
220 |
* Obtiene el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
|
221 |
* @return tipo de datos
|
222 |
*/
|
223 |
public int getDataType() { |
224 |
return dataType;
|
225 |
} |
226 |
|
227 |
/**
|
228 |
* Asigna el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
|
229 |
* @param dataType Tipo de dato del buffer
|
230 |
*/
|
231 |
public void setDataType(int dataType) { |
232 |
this.dataType = dataType;
|
233 |
} |
234 |
|
235 |
/**
|
236 |
* Obtiene el tama?o del tipo de dato en bytes
|
237 |
* @return Tipo de dato
|
238 |
*/
|
239 |
public int getDataSize() { |
240 |
if (dataType == TYPE_BYTE) {
|
241 |
return 1; |
242 |
} else if ((dataType == TYPE_SHORT) | (dataType == TYPE_USHORT)) { |
243 |
return 2; |
244 |
} else if (dataType == TYPE_INT) { |
245 |
return 4; |
246 |
}else if (dataType == TYPE_FLOAT) { |
247 |
return 8; |
248 |
}else if (dataType == TYPE_DOUBLE) { |
249 |
return 16; |
250 |
} |
251 |
|
252 |
return 0; |
253 |
} |
254 |
|
255 |
/**
|
256 |
* Obtiene el tama?o del buffer
|
257 |
* @return tama?o del buffer
|
258 |
*/
|
259 |
public long sizeof() { |
260 |
return getDataSize() * width * height * nBands;
|
261 |
} |
262 |
|
263 |
/**
|
264 |
* Replica la banda de una posici?n sobre otra. Si la banda de destino no existe
|
265 |
* se crea nueva. Si la posici?n de la banda de destino est? intercalada entre bandas
|
266 |
* que ya existen las otras se desplazan hacia abajo, NO se machacan los datos de ninguna.
|
267 |
* Los datos se replican por referencia por lo que al modificar la banda original las
|
268 |
* del resto quedar?n afectadas.
|
269 |
* @param orig. Posici?n de la banda de origen.
|
270 |
* @param dest. Posici?n de la banda destino
|
271 |
*/
|
272 |
public abstract void replicateBand(int orig, int dest); |
273 |
|
274 |
/**
|
275 |
* Cambia bandas de posici?n. Las posiciones deben existir como bandas del raster.
|
276 |
* Cada elemento del array representa una banda existente en el buffer (de longitud
|
277 |
* rasterBuf.length) y el valor contenido dentro la banda que le corresponde. Por ejemplo
|
278 |
* si pasamos un array {1, 0, 3, 2} significa que el buffer tiene cuatro bandas y que
|
279 |
* cambiamos la 0 por la 1 y la 2 por la 3. Un array {0, 1, 2, 3} en el mismo
|
280 |
* caso no producir?a nig?n cambio.
|
281 |
*
|
282 |
* Si quisieramos asignar en un buffer monobanda su banda a la segunda posici?n habria
|
283 |
* que insertar una vacia, por ejemplo con addBandFloat(0, null) se insertaria una
|
284 |
* banda nula en la posici?n 0 y la banda que estaba en la 0 pasar?a a la segunda.
|
285 |
*
|
286 |
*/
|
287 |
public abstract void switchBands(int[] bandPosition); |
288 |
|
289 |
/**
|
290 |
* Convierte un tipo de dato a cadena
|
291 |
* @param type Tipo de dato
|
292 |
* @return cadena que representa el tipo de dato
|
293 |
*/
|
294 |
public static String typesToString(int type) { |
295 |
switch (type) {
|
296 |
case RasterBuffer.TYPE_IMAGE:
|
297 |
return new String("Image"); |
298 |
|
299 |
case RasterBuffer.TYPE_BYTE:
|
300 |
return new String("Byte"); |
301 |
|
302 |
case RasterBuffer.TYPE_DOUBLE:
|
303 |
return new String("Double"); |
304 |
|
305 |
case RasterBuffer.TYPE_FLOAT:
|
306 |
return new String("Float"); |
307 |
|
308 |
case RasterBuffer.TYPE_INT:
|
309 |
return new String("Integer"); |
310 |
|
311 |
case RasterBuffer.TYPE_USHORT:
|
312 |
case RasterBuffer.TYPE_SHORT:
|
313 |
return new String("Short"); |
314 |
} |
315 |
|
316 |
return null; |
317 |
} |
318 |
|
319 |
/*
|
320 |
* (non-Javadoc)
|
321 |
* @see org.gvsig.raster.dataset.IBuffer#isInside(int, int)
|
322 |
*/
|
323 |
public boolean isInside(int x, int y) { |
324 |
if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight()) |
325 |
return false; |
326 |
return true; |
327 |
} |
328 |
|
329 |
/*
|
330 |
* (non-Javadoc)
|
331 |
* @see org.gvsig.fmap.driver.IBuffer#getNoDataValue()
|
332 |
*/
|
333 |
public double getNoDataValue() { |
334 |
return noDataValue;
|
335 |
} |
336 |
|
337 |
/*
|
338 |
* (non-Javadoc)
|
339 |
* @see org.gvsig.fmap.driver.IBuffer#getByteNoDataValue()
|
340 |
*/
|
341 |
public byte getByteNoDataValue() { |
342 |
return (byte)noDataValue; |
343 |
} |
344 |
|
345 |
/*
|
346 |
* (non-Javadoc)
|
347 |
* @see org.gvsig.fmap.driver.IBuffer#getShortNoDataValue()
|
348 |
*/
|
349 |
public short getShortNoDataValue(){ |
350 |
return (short)noDataValue; |
351 |
} |
352 |
|
353 |
/*
|
354 |
* (non-Javadoc)
|
355 |
* @see org.gvsig.fmap.driver.IBuffer#getIntNoDataValue()
|
356 |
*/
|
357 |
public int getIntNoDataValue(){ |
358 |
return (int)noDataValue; |
359 |
} |
360 |
|
361 |
/*
|
362 |
* (non-Javadoc)
|
363 |
* @see org.gvsig.fmap.driver.IBuffer#getFloatNoDataValue()
|
364 |
*/
|
365 |
public float getFloatNoDataValue(){ |
366 |
return (float)noDataValue; |
367 |
} |
368 |
|
369 |
/*
|
370 |
* (non-Javadoc)
|
371 |
* @see org.gvsig.fmap.driver.IBuffer#setNoDataValue(double)
|
372 |
*/
|
373 |
public void setNoDataValue(double nd){ |
374 |
noDataValue = nd; |
375 |
} |
376 |
|
377 |
/*
|
378 |
* (non-Javadoc)
|
379 |
* @see org.gvsig.fmap.driver.IBuffer#getNotValidValue()
|
380 |
*/
|
381 |
public double getNotValidValue(){ |
382 |
return notValidValue;
|
383 |
} |
384 |
|
385 |
/*
|
386 |
* (non-Javadoc)
|
387 |
* @see org.gvsig.fmap.driver.IBuffer#setNotValidValue(java.lang.Object)
|
388 |
*/
|
389 |
public void setNotValidValue(double value){ |
390 |
this.notValidValue = value;
|
391 |
} |
392 |
|
393 |
/*
|
394 |
* (non-Javadoc)
|
395 |
* @see org.gvsig.fmap.driver.IBuffer#cloneBuffer()
|
396 |
*/
|
397 |
public abstract IBuffer cloneBuffer(); |
398 |
|
399 |
/**
|
400 |
* Ajusta el ?rea del grid a un ancho y un alto dado en pixeles. Este ajuste se har?
|
401 |
* en relaci?n a un m?todo de interpolaci?n definido en el par?metro.
|
402 |
* @param w Ancho de la nueva imagen.
|
403 |
* @param h Alto de la nueva imagen.
|
404 |
* @param interpolation M?todo de interpolaci?n que se usar? en el ajuste.
|
405 |
*/
|
406 |
public RasterBuffer getAdjustedWindow(int w, int h, int interpolationMethod) throws InterruptedException { |
407 |
if (interp == null) |
408 |
interp = new BufferInterpolation(this); |
409 |
|
410 |
if (w == getWidth() && h == getHeight())
|
411 |
return this; |
412 |
RasterBuffer rasterBuf = null;
|
413 |
switch (interpolationMethod) {
|
414 |
case BufferInterpolation.INTERPOLATION_NearestNeighbour:
|
415 |
rasterBuf = interp.adjustRasterNearestNeighbourInterpolation(w, h); |
416 |
break;
|
417 |
case BufferInterpolation.INTERPOLATION_Bilinear:
|
418 |
rasterBuf = interp.adjustRasterBilinearInterpolation(w, h); |
419 |
break;
|
420 |
case BufferInterpolation.INTERPOLATION_InverseDistance:
|
421 |
rasterBuf = interp.adjustRasterInverseDistanceInterpolation(w, h); |
422 |
break;
|
423 |
case BufferInterpolation.INTERPOLATION_BicubicSpline:
|
424 |
rasterBuf = interp.adjustRasterBicubicSplineInterpolation(w, h); |
425 |
break;
|
426 |
case BufferInterpolation.INTERPOLATION_BSpline:
|
427 |
rasterBuf = interp.adjustRasterBSplineInterpolation(w, h); |
428 |
break;
|
429 |
} |
430 |
if (rasterBuf != null) |
431 |
return rasterBuf;
|
432 |
else
|
433 |
return this; |
434 |
} |
435 |
|
436 |
public BufferInterpolation getLastInterpolation() {
|
437 |
return interp;
|
438 |
} |
439 |
|
440 |
/*
|
441 |
* (non-Javadoc)
|
442 |
* @see org.gvsig.raster.dataset.IBuffer#getLimits()
|
443 |
*/
|
444 |
public double[] getLimits() throws InterruptedException { |
445 |
RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
|
446 |
double max = Double.NEGATIVE_INFINITY; |
447 |
double secondMax = max;
|
448 |
double min = Double.MAX_VALUE; |
449 |
double secondMin = min;
|
450 |
double value = 0; |
451 |
|
452 |
switch (getDataType()) {
|
453 |
case IBuffer.TYPE_BYTE:
|
454 |
for (int i = 0; i < getBandCount(); i++) |
455 |
for (int r = 0; r < getHeight(); r++) { |
456 |
for (int c = 0; c < getWidth(); c++) { |
457 |
value = (double) ((getElemByte(r, c, i)));
|
458 |
if (value > max) {
|
459 |
if (max != value) secondMax = max;
|
460 |
max = value; |
461 |
} |
462 |
if (value < min) {
|
463 |
if (min != value) secondMin = min;
|
464 |
min = value; |
465 |
} |
466 |
} |
467 |
if (task.getEvent() != null) |
468 |
task.manageEvent(task.getEvent()); |
469 |
} |
470 |
break;
|
471 |
case IBuffer.TYPE_SHORT:
|
472 |
for (int i = 0; i < getBandCount(); i++) |
473 |
for (int r = 0; r < getHeight(); r++) { |
474 |
for (int c = 0; c < getWidth(); c++) { |
475 |
value = (double) getElemShort(r, c, i);
|
476 |
if (value > max) {
|
477 |
if (max != value) secondMax = max;
|
478 |
max = value; |
479 |
} |
480 |
if (value < min) {
|
481 |
if (min != value) secondMin = min;
|
482 |
min = value; |
483 |
} |
484 |
} |
485 |
if (task.getEvent() != null) |
486 |
task.manageEvent(task.getEvent()); |
487 |
} |
488 |
break;
|
489 |
case IBuffer.TYPE_INT:
|
490 |
for (int i = 0; i < getBandCount(); i++) |
491 |
for (int r = 0; r < getHeight(); r++) { |
492 |
for (int c = 0; c < getWidth(); c++) { |
493 |
value = (double) getElemInt(r, c, i);
|
494 |
if (value > max) {
|
495 |
if (max != value) secondMax = max;
|
496 |
max = value; |
497 |
} |
498 |
if (value < min) {
|
499 |
if (min != value) secondMin = min;
|
500 |
min = value; |
501 |
} |
502 |
} |
503 |
if (task.getEvent() != null) |
504 |
task.manageEvent(task.getEvent()); |
505 |
} |
506 |
break;
|
507 |
case IBuffer.TYPE_FLOAT:
|
508 |
for (int i = 0; i < getBandCount(); i++) |
509 |
for (int r = 0; r < getHeight(); r++) { |
510 |
for (int c = 0; c < getWidth(); c++) { |
511 |
value = (double) getElemFloat(r, c, i);
|
512 |
if (value > max) {
|
513 |
if (max != value) secondMax = max;
|
514 |
max = value; |
515 |
} |
516 |
if (value < min) {
|
517 |
if (min != value) secondMin = min;
|
518 |
min = value; |
519 |
} |
520 |
} |
521 |
if (task.getEvent() != null) |
522 |
task.manageEvent(task.getEvent()); |
523 |
} |
524 |
break;
|
525 |
case IBuffer.TYPE_DOUBLE:
|
526 |
for (int i = 0; i < getBandCount(); i++) |
527 |
for (int r = 0; r < getHeight(); r++) { |
528 |
for (int c = 0; c < getWidth(); c++) { |
529 |
value = getElemDouble(r, c, i); |
530 |
if (value > max) {
|
531 |
if (max != value) secondMax = max;
|
532 |
max = value; |
533 |
} |
534 |
if (value < min) {
|
535 |
if (min != value) secondMin = min;
|
536 |
min = value; |
537 |
} |
538 |
} |
539 |
if (task.getEvent() != null) |
540 |
task.manageEvent(task.getEvent()); |
541 |
} |
542 |
break;
|
543 |
} |
544 |
// Si no existe un secondMax lo igualo al maximo existente
|
545 |
if (secondMax == Double.NEGATIVE_INFINITY) |
546 |
secondMax = max; |
547 |
// Si no existe un secondMin lo igualo al minimo existente
|
548 |
if (secondMin == Double.MAX_VALUE) |
549 |
secondMin = min; |
550 |
|
551 |
double[] values = new double[4]; |
552 |
values[0] = min;
|
553 |
values[1] = max;
|
554 |
values[2] = secondMin;
|
555 |
values[3] = secondMax;
|
556 |
return values;
|
557 |
} |
558 |
|
559 |
/*
|
560 |
* (non-Javadoc)
|
561 |
* @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
|
562 |
*/
|
563 |
public Histogram getHistogram() throws InterruptedException { |
564 |
RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
|
565 |
progressHistogram = 0;
|
566 |
Histogram hist = null;
|
567 |
double[] limits = getLimits(); |
568 |
|
569 |
if (limits == null) |
570 |
return null; |
571 |
|
572 |
if (getDataType() == IBuffer.TYPE_BYTE)
|
573 |
hist = new Histogram(getBandCount(), 256, limits[0], limits[1]); |
574 |
else
|
575 |
hist = new Histogram(getBandCount(), RasterLibrary.defaultNumberOfClasses, limits[0], limits[1]); |
576 |
|
577 |
for (int iBand = 0; iBand < getBandCount(); iBand++) { |
578 |
for (int row = 0; row < getHeight(); row++) { |
579 |
switch(getDataType()) {
|
580 |
case IBuffer.TYPE_BYTE:
|
581 |
for (int col = 0; col < getWidth(); col++) |
582 |
hist.incrementPxValue(iBand, (double)(getElemByte(row, col, iBand)));
|
583 |
break;
|
584 |
case IBuffer.TYPE_SHORT:
|
585 |
for (int col = 0; col < getWidth(); col++) |
586 |
hist.incrementPxValue(iBand, (double)(getElemShort(row, col, iBand)));
|
587 |
break;
|
588 |
case IBuffer.TYPE_INT:
|
589 |
for (int col = 0; col < getWidth(); col++) |
590 |
hist.incrementPxValue(iBand, (double)(getElemInt(row, col, iBand)));
|
591 |
break;
|
592 |
case IBuffer.TYPE_FLOAT:
|
593 |
for (int col = 0; col < getWidth(); col++) |
594 |
hist.incrementPxValue(iBand, (double)getElemFloat(row, col, iBand));
|
595 |
break;
|
596 |
case IBuffer.TYPE_DOUBLE:
|
597 |
for (int col = 0; col < getWidth(); col++) |
598 |
hist.incrementPxValue(iBand, getElemDouble(row, col, iBand)); |
599 |
break;
|
600 |
} |
601 |
|
602 |
if (task.getEvent() != null) |
603 |
task.manageEvent(task.getEvent()); |
604 |
|
605 |
progressHistogram = ((iBand*getHeight() + row) * 100) /(getHeight() * getBandCount());
|
606 |
} |
607 |
} |
608 |
progressHistogram = 100;
|
609 |
return hist;
|
610 |
} |
611 |
|
612 |
/*
|
613 |
* (non-Javadoc)
|
614 |
* @see org.gvsig.raster.util.IHistogramable#resetPercent()
|
615 |
*/
|
616 |
public void resetPercent() { |
617 |
switch(process) {
|
618 |
case HISTOGRAM_PROCESS: progressHistogram = 0; |
619 |
case INTERPOLATION_PROCESS: progressInterpolation = 0; |
620 |
} |
621 |
} |
622 |
|
623 |
/*
|
624 |
* (non-Javadoc)
|
625 |
* @see org.gvsig.raster.util.IHistogramable#getPercent()
|
626 |
*/
|
627 |
public int getPercent() { |
628 |
switch(process) {
|
629 |
case HISTOGRAM_PROCESS: return progressHistogram; |
630 |
case INTERPOLATION_PROCESS: return progressInterpolation; |
631 |
} |
632 |
return 0; |
633 |
} |
634 |
|
635 |
/**
|
636 |
* Asigna el proceso del cual se desea obtener informaci?n. Los procesos
|
637 |
* disponibles se definen como constantes en esta clase.
|
638 |
* @param process
|
639 |
*/
|
640 |
public void setProcess(int process) { |
641 |
this.process = process;
|
642 |
} |
643 |
} |