Revision 11478

View differences:

trunk/libraries/libRaster/src/org/gvsig/raster/dataset/RasterMultiDataset.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 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.dataset;
20

  
21
import java.awt.geom.Point2D;
22
import java.io.File;
23
import java.util.ArrayList;
24

  
25
import org.cresques.cts.IProjection;
26
import org.gvsig.raster.buffer.RasterBuffer;
27
import org.gvsig.raster.buffer.cache.RasterReadOnlyHugeBuffer;
28
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
29
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
30
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
31
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
32
import org.gvsig.raster.dataset.properties.DatasetPalette;
33
import org.gvsig.raster.dataset.properties.DatasetTransparency;
34
import org.gvsig.raster.shared.Extent;
35
import org.gvsig.raster.util.Histogram;
36
import org.gvsig.raster.util.HistogramException;
37
import org.gvsig.raster.util.IHistogramable;
38

  
39

  
40
/**
41
 * Clase que representa una imagen de raster georreferenciada formada por varias
42
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades para 
43
 * abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage con 
44
 * su gesti?n de bandas correspondiente.
45
 *  
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 *
48
 */
49
public class RasterMultiDataset implements IHistogramable {
50
	
51
	private boolean[]					cancel = new boolean[1];
52
	
53
	//File list
54
	private ArrayList 					files = new ArrayList();
55
	private String						name = null;
56
	//Band list
57
	private BandList					bandList = new BandList();
58
	private ArrayList					palettes = new ArrayList();
59
	protected DatasetListStatistics 		stats = null;
60
	protected DatasetListHistogram		histogram = null;
61
	int percent = 0;
62
			
63
	//TODO: FUNCIONALIDAD: Contructores igual a RasterDataset + String[] nameFiles
64
	public RasterMultiDataset(String name) {
65
		this.name = name;
66
	}
67
	
68
	/**
69
	 * Crea un objeto MultiRasterDataset nuevo con los mismos ficheros
70
	 * que el actual.
71
	 * @return MultiRasterDataset
72
	 */
73
	public RasterMultiDataset copyDataset() {
74
		try {
75
			String[] fileList = getNameDatasetStringList();
76
			RasterMultiDataset multiRasterDataset = RasterMultiDataset.open(getDataset(0).getProjection(), fileList[0]);
77
			for (int j = 1; j < fileList.length; j++)
78
				multiRasterDataset.addDataset(fileList[j]);
79
			return multiRasterDataset;
80
		} catch (FileNotFoundInListException e) {
81
			return null;
82
		} catch (NotSupportedExtensionException e) {
83
			return null;
84
		} catch (RasterDriverException e) {
85
			return null;
86
		}
87
	}
88
	
89
	/**
90
	 * Abre un dataset pasando como par?metros la proyecci?n y un objeto identificador del dataset. Este
91
	 * objeto puede ser una ruta a un fichero en disco. En este caso la extensi?n del fichero servir? para 
92
	 * buscar el driver que lo gestiona. Si proporcionamos un array de cadenas se tratar?n como la ruta a N ficheros
93
	 * de disco. Tambi?n puede ser un buffer de datos en memoria o cualquier otro objeto
94
	 * que pueda aceptar un driver.  
95
	 * @param proj PRoyecci?n
96
	 * @param datasetOpenParam Par?metros al driver
97
	 * @return RasterMultiDatset
98
	 * @throws NotSupportedExtensionException
99
	 * @throws RasterDriverException
100
	 */
101
	public static RasterMultiDataset open(IProjection proj, Object datasetOpenParam) throws NotSupportedExtensionException, RasterDriverException{
102
		RasterMultiDataset rmd = new RasterMultiDataset(null);
103
		if(datasetOpenParam instanceof String[]) {
104
			String[] param = (String[])datasetOpenParam;
105
			for (int dataset = 0; dataset < param.length; dataset++)
106
				try {
107
					rmd.addDataset(RasterDataset.open(proj, param[dataset]));
108
				} catch (FileNotFoundInListException e) {
109
					//No lo a?adimos en el dataset pq ya existe
110
				} 	
111
		} else if(datasetOpenParam instanceof IBuffer[]) {
112
			IBuffer[] param = (IBuffer[])datasetOpenParam;
113
			for (int dataset = 0; dataset < param.length; dataset++)
114
				try {
115
					rmd.addDataset(RasterDataset.open(proj, param[dataset]));
116
				} catch (FileNotFoundInListException e) {
117
					//No lo a?adimos en el dataset pq ya existe
118
				} 	
119
		} else {
120
			RasterDataset rd = RasterDataset.open(proj, datasetOpenParam);
121
			try {
122
				rmd.addDataset(rd);
123
			} catch (FileNotFoundInListException e) {
124
				//No lo a?adimos en el dataset pq ya existe
125
			}
126
		}
127
		return rmd;
128
	}
129
	
130
	/**
131
	 * Add a file to the list.
132
	 * @param f file to add.
133
	 */
134
	public void addDataset(RasterDataset f)throws FileNotFoundInListException {
135
		if(findDataset(f))
136
			throw new FileNotFoundInListException("The file already is in list.");
137
		files.add(f);
138
		addBands(f);
139
		stats = new DatasetListStatistics(files);
140
	}
141
	
142
	/**
143
	 * A?ade un fichero a la lista a partir de su nombre
144
	 * @param f fichero a a?adir.
145
	 * @throws RasterDriverException 
146
	 */
147
	public void addDataset(String fileName)throws FileNotFoundInListException, NotSupportedExtensionException, RasterDriverException{
148
		if(findDataset(fileName))
149
			throw new FileNotFoundInListException("The file already is in list.");
150
		RasterDataset f = RasterDataset.open(null, fileName);
151
		files.add(f);
152
		addBands(f);
153
		stats = new DatasetListStatistics(files);
154
	}
155
	
156
	/**
157
	 * A?ade el fichero a lista de georrasterfiles y sus bandas a la lista de bandas
158
	 * @param grf
159
	 */
160
	private void addBands(RasterDataset grf) {
161
		if(grf == null)
162
			return;
163
		
164
		int dataType = grf.getDataType();
165
		for(int i = 0; i < grf.getBandCount();i++) {
166
			try {
167
				Band band = new Band(grf.getFName(), i, dataType);
168
				bandList.addBand(band, i);
169
			} catch(BandNotFoundInListException ex) {
170
				//No a?adimos la banda
171
			}
172
		}
173
	}
174
	
175
	/**
176
	 * Elimina un fichero a la lista a partir de su nombre
177
	 * @param fileName	Nombre del fichero a eliminar.
178
	 */
179
	public void removeDataset(String fileName) {
180
		for(int i=0;i<files.size();i++) {
181
			if(((RasterDataset)files.get(i)).getFName().equals(fileName)) {
182
				files.remove(i);
183
				bandList.removeBands(fileName);
184
				return;
185
			}
186
		}
187
	}
188
	
189
	/**
190
	 * Elimina un fichero a la lista
191
	 * @param file Fichero a eliminar
192
	 */
193
	public void removeDataset(RasterDataset file) {
194
		for(int i=0;i<files.size();i++) {
195
			if(((RasterDataset)files.get(i)).getFName().equals(file.getFName())) {
196
				files.remove(i);
197
				bandList.removeBands(file.getFName());
198
				return;
199
			}
200
		}
201
	}
202
		
203
	/**
204
	 * Obtiene el n?mero de ficheros en la lista
205
	 * @return integer.
206
	 */
207
	public int getDatasetCount() {
208
		return files.size();
209
	}
210
	
211
	/**
212
	 * Encuentra un fichero en la lista.
213
	 * @param file Fichero b?scado.
214
	 * @return true si se ha hallado el fichero y false si no se 
215
	 * ha encontrado
216
	 */
217
	public boolean findDataset(RasterDataset file) {
218
		for(int i = 0;i<files.size();i++) {
219
			RasterDataset grf = (RasterDataset)files.get(i); 
220
			if(	grf.getFName().equals(file.getFName()))
221
				return true;
222
		}
223
		return false;
224
	}
225
	
226
	/**
227
	 * Encuentra un fichero en la lista.
228
	 * @param file Fichero b?scado.
229
	 * @return true si se ha hallado el fichero y false si no se 
230
	 * ha encontrado
231
	 */
232
	public boolean findDataset(String fileName) {
233
		for(int i = 0;i<files.size();i++) {
234
			if(((RasterDataset)files.get(i)).getFName().equals(fileName))
235
				return true;
236
		}
237
		return false;
238
	}
239
	    		
240
	/**
241
	 * @see org.javaGeoRaster.io.GeoInfo
242
	 */
243
	public void close() {
244
		for(int i = 0; i < files.size(); i++)
245
			((RasterDataset)files.get(i)).close();
246
	}
247
	
248
	/**
249
	 * Obtiene en un array de String la lista de nombres de ficheros
250
	 * @return lista de nombres de los ficheros del GeoRasterMultiFile
251
	 */
252
	public String[] getNameDatasetStringList() {
253
		String[] list = new String[files.size()];
254
		for(int i = 0; i < files.size(); i++)
255
			list[i] = ((RasterDataset)files.get(i)).getFName();
256
		return list;
257
	}
258
	
259
	/**
260
	 * Inicializa el buffer a valores NoData
261
	 * @param raster Buffer a inicializar
262
	 * @param bandList Lista de bandas
263
	 */
264
	private void initBufferToNoData(IBuffer raster, BandList bandList) {
265
		for(int i = 0; i < bandList.getDrawableBandsCount(); i++) {
266
			switch(getDataType()[0]) {
267
			case IBuffer.TYPE_BYTE:raster.assign(i, raster.getByteNoDataValue());break;
268
			case IBuffer.TYPE_SHORT:raster.assign(i, raster.getShortNoDataValue());break;
269
			case IBuffer.TYPE_INT:raster.assign(i, raster.getIntNoDataValue());break;
270
			case IBuffer.TYPE_FLOAT:raster.assign(i, raster.getFloatNoDataValue());break;
271
			case IBuffer.TYPE_DOUBLE:raster.assign(i, raster.getNoDataValue());break;
272
			}
273
		}	
274
	}
275
	
276
	/**
277
	 * A partir de la lista de bandas que dice como cargar el buffer se crean tantos IBuffer como ficheros intervienen
278
	 * . Cada IBuffer corresponde a un dataset del RasterMultiDataset y en ellos se reserva memoria solo para las
279
	 * bandas que vayan a ser cargadas. Las otras se asignaran a la banda NotValid.
280
	 * @param bl Lista de bandas
281
	 * @param width Ancho
282
	 * @param height Alto
283
	 * @return Lista de buffers en el que cada uno corresponde a un dataset.
284
	 */
285
	private IBuffer[] mallocBuffersDatasets(BandList bl, int width, int height) {
286
		IBuffer[] buffers = new IBuffer[getDatasetCount()];
287
		for(int i = 0; i < getDatasetCount(); i++) {
288
			buffers[i] =  RasterBuffer.getBuffer(getDataset(i).getDataType(), width, height, getDataset(i).getBandCount(), false);
289
			
290
			//Asignamos las bandas de cada fichero que no se pintan a null y las que se pintan se reserva memoria
291
			String name = getDataset(i).getFName();
292
			for(int j = 0; j < getDataset(i).getBandCount(); j ++) {
293
				if(bl.getBufferBandToDraw(name, j) == null)
294
					buffers[i].assignBandToNotValid(j);
295
				else
296
					buffers[i].mallocOneBand(getDataset(i).getDataType(), width, height, j);
297
			}
298
		}
299
		return buffers;
300
	}
301
	
302
	/**
303
	 * Mezcla los buffers de los dataset que forman el RasterMultiDataset sobre un solo buffer
304
	 * con las directrices que marca la lista de bandas. Esta funci?n es la que realiza el switch 
305
	 * de las bandas.
306
	 * @param b Buffer sobre el que se mezcla
307
	 * @param bDataset Buffers que corresponden a los datasets
308
	 * @param bandList Objeto que contiene la informaci?n de que bandas de los dataset se escriben sobre
309
	 * que banda del buffer.
310
	 */
311
	private void mergeBuffers(IBuffer b, IBuffer[] bDataset, BandList bandList) {
312
		for(int iDataset = 0; iDataset < getDatasetCount(); iDataset++){ //Ojo! Los datasets est?n en la misma posici?n que se han metido en mallocBuffersDatasets
313
			String name = getDataset(iDataset).getFName();
314
			
315
			System.out.println("");		
316
			System.out.println("4*............................");
317
			bandList.show();
318
			
319
			for(int iBand = 0; iBand < getDataset(iDataset).getBandCount(); iBand ++) {
320
				int[] posToDraw = bandList.getBufferBandToDraw(name, iBand);
321
				if(posToDraw != null) {
322
					for(int i = 0; i < posToDraw.length; i ++) {
323
						switch(getDataType()[iDataset]) {
324
						case IBuffer.TYPE_BYTE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
325
						case IBuffer.TYPE_SHORT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
326
						case IBuffer.TYPE_INT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
327
						case IBuffer.TYPE_FLOAT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
328
						case IBuffer.TYPE_DOUBLE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
329
						}
330
					}
331
				}
332
			}
333
		}
334
	}
335
	
336
	/**
337
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
338
	 * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
339
	 * pixeles de disco. 
340
	 * @param x Posici?n X superior izquierda
341
	 * @param y Posici?n Y superior izquierda
342
	 * @param w Ancho en coordenadas reales
343
	 * @param h Alto en coordenadas reales
344
	 * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
345
	 * @param bandList
346
	 * @return Buffer de datos
347
	 */
348
	public IBuffer getWindowRaster(double x, double y, double w, double h, boolean adjustToExtent) 
349
		throws InvalidSetViewException {
350
		
351
		Extent selectedExtent = new Extent(x, y, x + w, y - h);
352

  
353
		//Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
354
		//por arriba el m?s alto y por abajo el menor y luego restandolos
355
		
356
		Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x, y));
357
		Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x + w, y - h));
358
		int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
359
		int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
360
		
361
		int mallocNBands = 0;
362
		if(bandList.getDrawableArray() != null)
363
			mallocNBands = bandList.getDrawableArray().length;
364
		else
365
			bandList.getDrawableBandsCount();
366
		
367
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
368
		
369
		//Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
370
		if(!raster.isBandSwitchable()) {
371
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0).getBandCount(), false);
372
			if(rb instanceof RasterReadOnlyHugeBuffer) {
373
				try {
374
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
375
				} catch (FileNotExistsException e) {
376
					//Esto no debe darse ya que se comprueba al hacer el open
377
				} catch (NotSupportedExtensionException e) {
378
					//Esto no debe darse ya que se comprueba al hacer el open
379
				}
380
				return rb;
381
			}
382
				
383
		}
384
					
385
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
386
			raster.assignBandToNotValid(iBand);
387
		
388
		//Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
389
		//m?s grande y salirse de los l?mites.
390
		if(!adjustToExtent)
391
			 initBufferToNoData(raster, bandList);
392
		
393
		//Reservamos memoria para los buffers por dataset
394
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
395
		for(int i = 0; i < getDatasetCount(); i++)
396
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
397
			
398
		//Mezclamos los buffers de cada dataset en un solo buffer
399
		mergeBuffers(raster, bufferDatasets, bandList);
400
							
401
		return raster;
402
	}
403
			
404
	/**
405
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
406
	 * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
407
	 * el driver.
408
	 * @param minX Valor m?nimo de la X en coordenadas reales
409
	 * @param minY Valor m?nimo de la Y en coordenadas reales
410
	 * @param maxX Valor m?ximo de la X en coordenadas reales
411
	 * @param maxY Valor m?ximo de la Y en coordenadas reales
412
	 * @param bufWidth ancho del buffer lde datos
413
	 * @param bufHeight alto del buffer de datos
414
	 * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
415
	 * @param bandList
416
	 * @return Buffer de datos
417
	 */
418
	public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, 
419
									int bufWidth, int bufHeight, boolean adjustToExtent) throws InvalidSetViewException {
420
		
421
		if(	minX < ((RasterDataset)files.get(0)).getExtent().minX() || minY < ((RasterDataset)files.get(0)).getExtent().minY() ||
422
			maxX > ((RasterDataset)files.get(0)).getExtent().maxX() || maxY > ((RasterDataset)files.get(0)).getExtent().maxY())
423
				throw new InvalidSetViewException("");
424
		
425
		int mallocNBands = 0;
426
		if(bandList.getDrawableArray() != null)
427
			mallocNBands = bandList.getDrawableArray().length;
428
		else
429
			bandList.getDrawableBandsCount();
430
		
431
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
432
		
433
		//TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
434
		//Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
435
		/*if(!raster.isBandSwitchable()) {
436
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
437
			if(rb instanceof RasterReadOnlyHugeBuffer) {
438
				try {
439
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
440
				} catch (FileNotExistsException e) {
441
					//Esto no debe darse ya que se comprueba al hacer el open
442
				} catch (NotSupportedExtensionException e) {
443
					//Esto no debe darse ya que se comprueba al hacer el open
444
				}
445
				return rb;
446
			}
447
		}*/
448
			
449
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
450
			raster.assignBandToNotValid(iBand);
451
		
452
		//Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
453
		//m?s grande y salirse de los l?mites.
454
		if(!adjustToExtent)
455
			 initBufferToNoData(raster, bandList);	
456
		
457
		//Reservamos memoria para los buffers por dataset
458
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
459
		for(int i = 0; i < getDatasetCount(); i++)
460
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(minX, minY, maxX, maxY, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
461
		
462
		//Mezclamos los buffers de cada dataset en un solo buffer
463
		mergeBuffers(raster, bufferDatasets, bandList);
464
							
465
		return raster;
466
	}
467
	
468
	/**
469
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
470
	 * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
471
	 * pixeles de disco. 
472
	 * @param x Posici?n X superior izquierda
473
	 * @param y Posici?n Y superior izquierda
474
	 * @param w Ancho en coordenadas pixel
475
	 * @param h Alto en coordenadas pixel
476
	 * @param bandList
477
	 * @return Buffer de datos
478
	 */
479
	public IBuffer getWindowRaster(int x, int y, int w, int h) throws InvalidSetViewException {
480
		if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
481
			throw new InvalidSetViewException("Out of image");
482
		
483
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
484
		
485
		//Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
486
		if(!raster.isBandSwitchable()) {
487
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], w, h, getDataset(0).getBandCount(), false);
488
			if(rb instanceof RasterReadOnlyHugeBuffer) {
489
				try {
490
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
491
				} catch (FileNotExistsException e) {
492
					//Esto no debe darse ya que se comprueba al hacer el open
493
				} catch (NotSupportedExtensionException e) {
494
					//Esto no debe darse ya que se comprueba al hacer el open
495
				}
496
				return rb;
497
			}
498
		}
499
				
500
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
501
			raster.assignBandToNotValid(iBand);
502
		
503
		//Reservamos memoria para los buffers por dataset
504
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
505
		for(int i = 0; i < getDatasetCount(); i++)
506
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
507
		
508
		//Mezclamos los buffers de cada dataset en un solo buffer
509
		mergeBuffers(raster, bufferDatasets, bandList);
510
							
511
		return raster;
512
	}
513
	
514
	/**
515
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
516
	 * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
517
	 * @param x Posici?n X superior izquierda en pixels
518
	 * @param y Posici?n Y superior izquierda en pixels
519
	 * @param w Ancho en pixels
520
	 * @param h Alto en pixels
521
	 * @param bufWidth ancho del buffer de datos
522
	 * @param bufHeight alto del buffer de datos
523
	 * @param bandList
524
	 * @return Buffer de datos
525
	 */
526
	public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)  
527
		throws InvalidSetViewException {
528
		if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
529
			throw new InvalidSetViewException("Out of image");
530
				
531
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
532
			
533
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
534
			raster.assignBandToNotValid(iBand);
535
			
536
		//Reservamos memoria para los buffers por dataset
537
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
538
		
539
		//TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
540
		//Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
541
		/*if(!raster.isBandSwitchable()) {
542
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
543
			if(rb instanceof RasterReadOnlyHugeBuffer) {
544
				try {
545
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
546
				} catch (FileNotExistsException e) {
547
					//Esto no debe darse ya que se comprueba al hacer el open
548
				} catch (NotSupportedExtensionException e) {
549
					//Esto no debe darse ya que se comprueba al hacer el open
550
				}
551
				return rb;
552
			}
553
		}*/
554
			
555
		for(int i = 0; i < getDatasetCount(); i++)
556
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
557

  
558
		//Mezclamos los buffers de cada dataset en un solo buffer
559
		mergeBuffers(raster, bufferDatasets, bandList);
560
							
561
		return raster;
562
	}
563
	
564
	//******************************
565
	//Setters and Getters
566
	//******************************
567
	
568
	/**
569
	 * Calcula el tama?o de los ficheros en disco
570
	 * @return tama?o en bytes de todos los ficheros de la lista
571
	 */
572
	public long getFileSize(){
573
		int len = 0;
574
		for(int i=0;i<files.size();i++){
575
			if(((RasterDataset)files.get(i)) != null){
576
				File f = new File(((RasterDataset)files.get(i)).getFName());
577
				len += f.length();
578
			}
579
		}
580
		return len;
581
	}
582
	
583
	/**
584
	 * Obtiene la altura de la imagen a partir de la primera
585
	 * @return altura
586
	 */
587
	public double[] getHeight() {
588
		double[] lenghts = new double[getDatasetCount()];
589
		for(int i = 0; i < getDatasetCount(); i++)
590
			if(((RasterDataset)files.get(i)) != null)
591
				lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
592
		return lenghts;
593
	}
594

  
595
	/**
596
	 * Obtiene la anchura de la imagen a partir de la primera
597
	 * @return anchura
598
	 */
599
	public double[] getWidth() {
600
		double[] lenghts = new double[getDatasetCount()];
601
		for(int i = 0; i < getDatasetCount(); i++)
602
			if(((RasterDataset)files.get(i)) != null)
603
				lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
604
		return lenghts;	
605
	}
606
	
607
	/**
608
	 * Obtiene el n?mero de bandas del fichero
609
	 * @return
610
	 */
611
	public int getBandCount(){
612
		return bandList.getBandCount();
613
	}
614

  
615
	/**
616
	 * Obtiene el tipo de dato por banda
617
	 * @return tipo de dato por banda
618
	 */
619
	public int[] getDataType() {
620
		int[] dt = new int[getDatasetCount()];
621
		for(int i=0;i<files.size();i++)
622
			dt[i] = ((RasterDataset)files.get(i)).getDataType();
623
				
624
	    if(dt.length == 0)
625
	    	return null;
626
	    else
627
	    	return dt;
628
	}
629
	
630
	/**
631
	 * Obtiene fichero de la posici?n i.
632
	 * @param i Posici?n del fichero a obtener.
633
	 * @return GeoRasterFileDataset.
634
	 */
635
	public RasterDataset getDataset(int i){
636
		return (RasterDataset)files.get(i);
637
	}
638
	
639
	/**
640
	 * Obtiene fichero de nombre fileName.
641
	 * @param i Posici?n del fichero a obtener.
642
	 * @return GeoRasterFile.
643
	 */
644
	public RasterDataset getDataset(String fileName){
645
		for(int i=0;i<files.size();i++){
646
			if(((RasterDataset)files.get(i)).getFName().equals(fileName))
647
				return (RasterDataset)files.get(i); 
648
		}
649
		return null;		
650
	}
651
	
652
	/**
653
	 * Asigna el nombre al GeoRasterMultiFile
654
	 * @param name Nombre del GeoRasterMultiFile
655
	 */
656
	public void setName(String name){
657
		this.name = name;
658
	}
659
	
660
	/**
661
	 * Obtiene la lista de bandas
662
	 * @return BandList
663
	 */
664
	public BandList getBands(){
665
		return bandList;
666
	}
667
	
668
	/**
669
	 * Obtiene la coordenada X m?nima de toda la lista
670
	 * @return Coordenada X m?nima
671
	 */
672
	public double getMinX(){
673
		double minx = Double.MAX_VALUE;
674
		for(int i = 0; i < files.size(); i++){
675
			double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
676
			if(aux < minx)
677
				minx = aux;
678
		}
679
		return minx;
680
	}
681
	
682
	/**
683
	 * Obtiene la coordenada Y m?nima de toda la lista
684
	 * @return Coordenada Y m?nima
685
	 */
686
	public double getMinY(){
687
		double miny = Double.MAX_VALUE;
688
		for(int i = 0; i < files.size(); i++){
689
			double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
690
			if(aux < miny)
691
				miny = aux;
692
		}
693
		return miny;
694
	}
695
	
696
	/**
697
	 * Obtiene la coordenada Y m?xima de toda la lista
698
	 * @return Coordenada Y m?xima
699
	 */
700
	public double getMaxX(){
701
		double maxx = Double.NEGATIVE_INFINITY;
702
		for(int i = 0; i < files.size(); i++){
703
			double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
704
			if(aux > maxx)
705
				maxx = aux;
706
		}
707
		return maxx;
708
	}
709

  
710
	/**
711
	 * Obtiene la coordenada Y m?xima de toda la lista
712
	 * @return Coordenada Y m?xima
713
	 */
714
	public double getMaxY(){
715
		double maxy = Double.NEGATIVE_INFINITY;
716
		for(int i = 0; i < files.size(); i++){
717
			double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
718
			if(aux > maxy)
719
				maxy = aux;
720
		}
721
		return maxy;
722
	}
723
	
724
	/**
725
	 * Obtiene el extent del multi fichero. Este corresponde al primer
726
	 * GeoRasterFile de la lista.
727
	 * @return Extent
728
	 */
729
	public Extent getExtent(){
730
		if(files.size() == 0)
731
			return null;
732
		else
733
			return ((RasterDataset)files.get(0)).getExtent();
734
	}
735
	
736
	/**
737
     * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
738
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
739
     * pero para un raster rotado ser? igual al extent del raster como si no 
740
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
741
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
742
     * aplicado.
743
     * @return Extent
744
     */
745
    public Extent getExtentForRequest() {
746
        return ((RasterDataset)files.get(0)).getExtentForRequest();
747
    }
748
	
749
	/**
750
	 * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado 
751
	 * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
752
	 * las coordenadas pixel de la misma 
753
	 * @return Array de seis valores:
754
	 * 	<TABLE BORDER="1">
755
	 * 	<TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
756
	 * 	<TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
757
	 * 	<TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
758
	 * 	<TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
759
	 * 	<TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
760
	 * 	<TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
761
	 * 	</TABLE>
762
	 */
763
	public double[] getCoordsGeoTransformFile(){
764
		return ((RasterDataset)files.get(0)).getTransform();
765
	}
766
	
767
	/**
768
	 * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
769
	 * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
770
	 * que se hayan aplicado sobre el/los dataset.
771
	 * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
772
	 * solicitada.
773
	 */
774
	public Extent getLastSelectedView(){
775
		return ((RasterDataset)files.get(0)).getView();
776
	}
777
	
778
	/**
779
	 * Obtiene el tama?o de pixel.
780
	 * @return array de dos elementos, tama?o de pixel en X y en Y.
781
	 */
782
	public double[] getPixelSize(){
783
		double[] at = ((RasterDataset)files.get(0)).getTransform();
784
		return new double[]{at[1], at[5]};
785
	}
786
	
787
	/**
788
	 * Obtiene el estado de transparencia a partir de los estados de transparencia de todos
789
	 * los ficheros que lo componen. Si varios de los ficheros que lo componen tienen banda de 
790
	 * transparencia estas tendr?n que ser mezcladas sobre una banda de transparencia ?nica.
791
	 * @return Objeto FileTransparency con el estado de transparencia
792
	 */
793
	public DatasetListTransparency getTransparencyFilesStatus(){
794
		DatasetListTransparency out = null;
795
		for(int i = 0; i < files.size(); i++){
796
			DatasetTransparency tfs = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
797
			if(tfs != null){
798
				if(out == null)
799
					out = new DatasetListTransparency(tfs);
800
				else
801
					out.merge(tfs);
802
			}
803
		}
804
		return out;
805
	}
806
	
807
	/**
808
	 * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
809
	 * @param i Posici?n del raster
810
	 * @return Paleta asociada a este o null si no tiene
811
	 */
812
	public DatasetPalette getPalette(int i){
813
		if(i >= files.size())
814
			return null;
815
		return ((RasterDataset)files.get(i)).getPalette();
816
	}
817
	
818
	/**
819
	 * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
820
	 * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
821
	 * para ese fichero no hay paletas asociadas.
822
	 */
823
	public DatasetPalette[] getPalettes(){
824
		if(files.size() <= 0)
825
			return null;
826
		DatasetPalette[] list = new DatasetPalette[files.size()];
827
		for(int i = 0; i < files.size(); i++)
828
			list[i] = ((RasterDataset)files.get(i)).getPalette();
829
		return list;
830
	}
831
	
832
	/**
833
	 * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
834
	 * @param fileName Nombre del fichero
835
	 * @return Paleta o null si no la tiene
836
	 */
837
	public DatasetPalette getPalette(String fileName){
838
		for(int i = 0; i < files.size(); i++){
839
			if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
840
				return ((RasterDataset)files.get(i)).getPalette();
841
		}
842
		return null;
843
	}
844
	
845
	/**
846
	 * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
847
	 * @param pt Punto a transformar
848
	 * @return punto transformado en coordenadas del mundo
849
	 */
850
	public Point2D rasterToWorld(Point2D pt) {
851
		return ((RasterDataset)files.get(0)).rasterToWorld(pt);
852
	}
853
	
854
	/**
855
	 * Convierte un punto desde del mundo a coordenadas pixel.
856
	 * @param pt Punto a transformar
857
	 * @return punto transformado en coordenadas pixel
858
	 */
859
	public Point2D worldToRaster(Point2D pt) {
860
		return ((RasterDataset)files.get(0)).worldToRaster(pt);
861
	}
862
	
863
	/**
864
	 * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
865
	 * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
866
	 * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
867
	 * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
868
	 * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
869
	 * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
870
	 * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
871
	 * el driver autom?ticamente.
872
	 * @param dWorldTLX Coordenada real X superior izquierda
873
	 * @param dWorldTLY Coordenada real Y superior izquierda
874
	 * @param nWidth Ancho del raster
875
	 * @param nHeight Alto del raster
876
	 * @param bufWidth Ancho del buffer
877
	 * @param bufHeight Alto del buffer
878
	 * @return Array de dos elementos con el desplazamiento en X e Y. 
879
	 */
880
	public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
881
			double nWidth, double nHeight, int bufWidth, int bufHeight){
882
		return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
883
	}
884
	
885
	/**
886
	 * Obtiene el objeto con las estadisticas
887
	 * @return MultiFileStatistics
888
	 */
889
	public DatasetListStatistics getStatistics(){
890
		return stats;
891
	}
892
	
893
	/**
894
	 * Obtiene el flag que dice si la imagen est? o no georreferenciada
895
	 * @return true si est? georreferenciada y false si no lo est?.
896
	 */
897
	public boolean isGeoreferenced() {
898
		for(int i = 0; i < files.size(); i++){
899
			if(((RasterDataset)files.get(i)).isGeoreferenced())
900
				return true;
901
		}
902
		return false;
903
	}
904

  
905
	//TODO: TEST: Probar getData para multifichero
906
	/**
907
	 * Obtiene el valor del raster en la coordenada que se le pasa.
908
	 * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
909
	 * raster.
910
	 * @param x	coordenada X
911
	 * @param y coordenada Y
912
	 * @return
913
	 */
914
	public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
915
		String file = bandList.getBand(band).getFileName();
916
		for(int i = 0; i < files.size(); i++){
917
			if(((RasterDataset)files.get(i)).getFName().equals(file))
918
				return ((RasterDataset)files.get(i)).getData(x, y, band); 
919
		}
920
		return null;
921
	}
922
		
923
	/**
924
	 * Obtiene el objeto que contiene que contiene la interpretaci?n de 
925
	 * color por banda para el dataset seleccionado
926
	 * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
927
	 * @return DatasetColorInterpretation
928
	 */
929
	public DatasetColorInterpretation getColorInterpretation(int dataset){
930
		return ((RasterDataset)files.get(dataset)).getColorInterpretation();
931
	}
932
	
933
	/**
934
	 * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
935
	 * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
936
	 * dataset.
937
	 * @return Proyecci?n en formato cadena
938
	 * @throws RasterDriverException
939
	 */
940
	public String getStringProjection() throws RasterDriverException{
941
		return ((RasterDataset)files.get(0)).getStringProjection();
942
	}
943

  
944
	/*
945
	 * (non-Javadoc)
946
	 * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
947
	 */
948
	public Histogram getHistogram() throws HistogramException {
949
		if (histogram == null)
950
			histogram = new DatasetListHistogram(this);
951
		
952
		try {
953
			Histogram tmpHist = histogram.getHistogram();
954
			return tmpHist;
955
		} catch (FileNotOpenException e) {
956
			throw new HistogramException("FileNotOpenException");
957
		} catch (RasterDriverException e) {
958
			throw new HistogramException("RasterDriverException");
959
		}
960
	}
961

  
962
	/*
963
	 * (non-Javadoc)
964
	 * @see org.gvsig.raster.util.IHistogramable#getPercent()
965
	 */
966
	public int getPercent() {
967
		if (histogram != null) return histogram.getPercent();
968
		return 0;
969
	}
970
	
971
	
972
	/*
973
	 * (non-Javadoc)
974
	 * @see org.gvsig.raster.util.IHistogramable#resetPercent()
975
	 */
976
	public void resetPercent() {
977
		if (histogram != null) histogram.resetPercent();
978
	}
979

  
980
	/*
981
	 * (non-Javadoc)
982
	 * @see org.gvsig.raster.util.ICancellable#isCanceled()
983
	 */
984
	public boolean isCanceled(int process) {
985
		if(process == CANCEL_HISTOGRAM) {
986
			if (histogram != null) 
987
				return histogram.isCanceled(0);
988
		}
989
		return false;
990
	}
991

  
992
	/*
993
	 * (non-Javadoc)
994
	 * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
995
	 */
996
	public void setCanceled(boolean value, int process) {
997
		if(process == CANCEL_HISTOGRAM || process == 0) 
998
			if (histogram != null) 
999
				histogram.setCanceled(value, 0);
1000
			
1001
	}
1002
}
trunk/libraries/libRaster/src/org/gvsig/raster/dataset/properties/DatasetListHistogram.java
21 21
import org.gvsig.raster.dataset.FileNotOpenException;
22 22
import org.gvsig.raster.dataset.RasterDataset;
23 23
import org.gvsig.raster.dataset.RasterDriverException;
24
import org.gvsig.raster.dataset.RasterMultiDataset;
24
import org.gvsig.raster.dataset.MultiRasterDataset;
25 25
import org.gvsig.raster.util.Histogram;
26 26

  
27 27
/**
......
39 39
	/**
40 40
	 * Dataset del cual se calcula el histograma
41 41
	 */
42
	private RasterMultiDataset	multiDataset = null;
42
	private MultiRasterDataset	multiDataset = null;
43 43
	
44 44
	/**
45 45
	 * Constructor
46 46
	 * @param dataset
47 47
	 */
48
	public DatasetListHistogram(RasterMultiDataset dataset){
48
	public DatasetListHistogram(MultiRasterDataset dataset){
49 49
		this.multiDataset = dataset;
50 50
	}
51 51
	
trunk/libraries/libRaster/src/org/gvsig/raster/dataset/MultiRasterDataset.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 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.dataset;
20

  
21
import java.awt.geom.Point2D;
22
import java.io.File;
23
import java.util.ArrayList;
24

  
25
import org.cresques.cts.IProjection;
26
import org.gvsig.raster.buffer.RasterBuffer;
27
import org.gvsig.raster.buffer.cache.RasterReadOnlyHugeBuffer;
28
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
29
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
30
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
31
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
32
import org.gvsig.raster.dataset.properties.DatasetPalette;
33
import org.gvsig.raster.dataset.properties.DatasetTransparency;
34
import org.gvsig.raster.shared.Extent;
35
import org.gvsig.raster.util.Histogram;
36
import org.gvsig.raster.util.HistogramException;
37
import org.gvsig.raster.util.IHistogramable;
38

  
39

  
40
/**
41
 * Clase que representa una imagen de raster georreferenciada formada por varias
42
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades para 
43
 * abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage con 
44
 * su gesti?n de bandas correspondiente.
45
 *  
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 *
48
 */
49
public class MultiRasterDataset implements IHistogramable {
50
	
51
	private boolean[]					cancel = new boolean[1];
52
	
53
	//File list
54
	private ArrayList 					files = new ArrayList();
55
	private String						name = null;
56
	//Band list
57
	private BandList					bandList = new BandList();
58
	private ArrayList					palettes = new ArrayList();
59
	protected DatasetListStatistics 		stats = null;
60
	protected DatasetListHistogram		histogram = null;
61
	int percent = 0;
62
			
63
	//TODO: FUNCIONALIDAD: Contructores igual a RasterDataset + String[] nameFiles
64
	public MultiRasterDataset(String name) {
65
		this.name = name;
66
	}
67
	
68
	/**
69
	 * Crea un objeto MultiRasterDataset nuevo con los mismos ficheros
70
	 * que el actual.
71
	 * @return MultiRasterDataset
72
	 */
73
	public MultiRasterDataset copyDataset() {
74
		try {
75
			String[] fileList = getNameDatasetStringList();
76
			MultiRasterDataset multiRasterDataset = MultiRasterDataset.open(getDataset(0).getProjection(), fileList[0]);
77
			for (int j = 1; j < fileList.length; j++)
78
				multiRasterDataset.addDataset(fileList[j]);
79
			return multiRasterDataset;
80
		} catch (FileNotFoundInListException e) {
81
			return null;
82
		} catch (NotSupportedExtensionException e) {
83
			return null;
84
		} catch (RasterDriverException e) {
85
			return null;
86
		}
87
	}
88
	
89
	/**
90
	 * Abre un dataset pasando como par?metros la proyecci?n y un objeto identificador del dataset. Este
91
	 * objeto puede ser una ruta a un fichero en disco. En este caso la extensi?n del fichero servir? para 
92
	 * buscar el driver que lo gestiona. Si proporcionamos un array de cadenas se tratar?n como la ruta a N ficheros
93
	 * de disco. Tambi?n puede ser un buffer de datos en memoria o cualquier otro objeto
94
	 * que pueda aceptar un driver.  
95
	 * @param proj PRoyecci?n
96
	 * @param datasetOpenParam Par?metros al driver
97
	 * @return RasterMultiDatset
98
	 * @throws NotSupportedExtensionException
99
	 * @throws RasterDriverException
100
	 */
101
	public static MultiRasterDataset open(IProjection proj, Object datasetOpenParam) throws NotSupportedExtensionException, RasterDriverException{
102
		MultiRasterDataset rmd = new MultiRasterDataset(null);
103
		if(datasetOpenParam instanceof String[]) {
104
			String[] param = (String[])datasetOpenParam;
105
			for (int dataset = 0; dataset < param.length; dataset++)
106
				try {
107
					rmd.addDataset(RasterDataset.open(proj, param[dataset]));
108
				} catch (FileNotFoundInListException e) {
109
					//No lo a?adimos en el dataset pq ya existe
110
				} 	
111
		} else if(datasetOpenParam instanceof IBuffer[]) {
112
			IBuffer[] param = (IBuffer[])datasetOpenParam;
113
			for (int dataset = 0; dataset < param.length; dataset++)
114
				try {
115
					rmd.addDataset(RasterDataset.open(proj, param[dataset]));
116
				} catch (FileNotFoundInListException e) {
117
					//No lo a?adimos en el dataset pq ya existe
118
				} 	
119
		} else {
120
			RasterDataset rd = RasterDataset.open(proj, datasetOpenParam);
121
			try {
122
				rmd.addDataset(rd);
123
			} catch (FileNotFoundInListException e) {
124
				//No lo a?adimos en el dataset pq ya existe
125
			}
126
		}
127
		return rmd;
128
	}
129
	
130
	/**
131
	 * Add a file to the list.
132
	 * @param f file to add.
133
	 */
134
	public void addDataset(RasterDataset f)throws FileNotFoundInListException {
135
		if(findDataset(f))
136
			throw new FileNotFoundInListException("The file already is in list.");
137
		files.add(f);
138
		addBands(f);
139
		stats = new DatasetListStatistics(files);
140
	}
141
	
142
	/**
143
	 * A?ade un fichero a la lista a partir de su nombre
144
	 * @param f fichero a a?adir.
145
	 * @throws RasterDriverException 
146
	 */
147
	public void addDataset(String fileName)throws FileNotFoundInListException, NotSupportedExtensionException, RasterDriverException{
148
		if(findDataset(fileName))
149
			throw new FileNotFoundInListException("The file already is in list.");
150
		RasterDataset f = RasterDataset.open(null, fileName);
151
		files.add(f);
152
		addBands(f);
153
		stats = new DatasetListStatistics(files);
154
	}
155
	
156
	/**
157
	 * A?ade el fichero a lista de georrasterfiles y sus bandas a la lista de bandas
158
	 * @param grf
159
	 */
160
	private void addBands(RasterDataset grf) {
161
		if(grf == null)
162
			return;
163
		
164
		int dataType = grf.getDataType();
165
		for(int i = 0; i < grf.getBandCount();i++) {
166
			try {
167
				Band band = new Band(grf.getFName(), i, dataType);
168
				bandList.addBand(band, i);
169
			} catch(BandNotFoundInListException ex) {
170
				//No a?adimos la banda
171
			}
172
		}
173
	}
174
	
175
	/**
176
	 * Elimina un fichero a la lista a partir de su nombre
177
	 * @param fileName	Nombre del fichero a eliminar.
178
	 */
179
	public void removeDataset(String fileName) {
180
		for(int i=0;i<files.size();i++) {
181
			if(((RasterDataset)files.get(i)).getFName().equals(fileName)) {
182
				files.remove(i);
183
				bandList.removeBands(fileName);
184
				return;
185
			}
186
		}
187
	}
188
	
189
	/**
190
	 * Elimina un fichero a la lista
191
	 * @param file Fichero a eliminar
192
	 */
193
	public void removeDataset(RasterDataset file) {
194
		for(int i=0;i<files.size();i++) {
195
			if(((RasterDataset)files.get(i)).getFName().equals(file.getFName())) {
196
				files.remove(i);
197
				bandList.removeBands(file.getFName());
198
				return;
199
			}
200
		}
201
	}
202
		
203
	/**
204
	 * Obtiene el n?mero de ficheros en la lista
205
	 * @return integer.
206
	 */
207
	public int getDatasetCount() {
208
		return files.size();
209
	}
210
	
211
	/**
212
	 * Encuentra un fichero en la lista.
213
	 * @param file Fichero b?scado.
214
	 * @return true si se ha hallado el fichero y false si no se 
215
	 * ha encontrado
216
	 */
217
	public boolean findDataset(RasterDataset file) {
218
		for(int i = 0;i<files.size();i++) {
219
			RasterDataset grf = (RasterDataset)files.get(i); 
220
			if(	grf.getFName().equals(file.getFName()))
221
				return true;
222
		}
223
		return false;
224
	}
225
	
226
	/**
227
	 * Encuentra un fichero en la lista.
228
	 * @param file Fichero b?scado.
229
	 * @return true si se ha hallado el fichero y false si no se 
230
	 * ha encontrado
231
	 */
232
	public boolean findDataset(String fileName) {
233
		for(int i = 0;i<files.size();i++) {
234
			if(((RasterDataset)files.get(i)).getFName().equals(fileName))
235
				return true;
236
		}
237
		return false;
238
	}
239
	    		
240
	/**
241
	 * @see org.javaGeoRaster.io.GeoInfo
242
	 */
243
	public void close() {
244
		for(int i = 0; i < files.size(); i++)
245
			((RasterDataset)files.get(i)).close();
246
	}
247
	
248
	/**
249
	 * Obtiene en un array de String la lista de nombres de ficheros
250
	 * @return lista de nombres de los ficheros del GeoRasterMultiFile
251
	 */
252
	public String[] getNameDatasetStringList() {
253
		String[] list = new String[files.size()];
254
		for(int i = 0; i < files.size(); i++)
255
			list[i] = ((RasterDataset)files.get(i)).getFName();
256
		return list;
257
	}
258
	
259
	/**
260
	 * Inicializa el buffer a valores NoData
261
	 * @param raster Buffer a inicializar
262
	 * @param bandList Lista de bandas
263
	 */
264
	private void initBufferToNoData(IBuffer raster, BandList bandList) {
265
		for(int i = 0; i < bandList.getDrawableBandsCount(); i++) {
266
			switch(getDataType()[0]) {
267
			case IBuffer.TYPE_BYTE:raster.assign(i, raster.getByteNoDataValue());break;
268
			case IBuffer.TYPE_SHORT:raster.assign(i, raster.getShortNoDataValue());break;
269
			case IBuffer.TYPE_INT:raster.assign(i, raster.getIntNoDataValue());break;
270
			case IBuffer.TYPE_FLOAT:raster.assign(i, raster.getFloatNoDataValue());break;
271
			case IBuffer.TYPE_DOUBLE:raster.assign(i, raster.getNoDataValue());break;
272
			}
273
		}	
274
	}
275
	
276
	/**
277
	 * A partir de la lista de bandas que dice como cargar el buffer se crean tantos IBuffer como ficheros intervienen
278
	 * . Cada IBuffer corresponde a un dataset del RasterMultiDataset y en ellos se reserva memoria solo para las
279
	 * bandas que vayan a ser cargadas. Las otras se asignaran a la banda NotValid.
280
	 * @param bl Lista de bandas
281
	 * @param width Ancho
282
	 * @param height Alto
283
	 * @return Lista de buffers en el que cada uno corresponde a un dataset.
284
	 */
285
	private IBuffer[] mallocBuffersDatasets(BandList bl, int width, int height) {
286
		IBuffer[] buffers = new IBuffer[getDatasetCount()];
287
		for(int i = 0; i < getDatasetCount(); i++) {
288
			buffers[i] =  RasterBuffer.getBuffer(getDataset(i).getDataType(), width, height, getDataset(i).getBandCount(), false);
289
			
290
			//Asignamos las bandas de cada fichero que no se pintan a null y las que se pintan se reserva memoria
291
			String name = getDataset(i).getFName();
292
			for(int j = 0; j < getDataset(i).getBandCount(); j ++) {
293
				if(bl.getBufferBandToDraw(name, j) == null)
294
					buffers[i].assignBandToNotValid(j);
295
				else
296
					buffers[i].mallocOneBand(getDataset(i).getDataType(), width, height, j);
297
			}
298
		}
299
		return buffers;
300
	}
301
	
302
	/**
303
	 * Mezcla los buffers de los dataset que forman el RasterMultiDataset sobre un solo buffer
304
	 * con las directrices que marca la lista de bandas. Esta funci?n es la que realiza el switch 
305
	 * de las bandas.
306
	 * @param b Buffer sobre el que se mezcla
307
	 * @param bDataset Buffers que corresponden a los datasets
308
	 * @param bandList Objeto que contiene la informaci?n de que bandas de los dataset se escriben sobre
309
	 * que banda del buffer.
310
	 */
311
	private void mergeBuffers(IBuffer b, IBuffer[] bDataset, BandList bandList) {
312
		for(int iDataset = 0; iDataset < getDatasetCount(); iDataset++){ //Ojo! Los datasets est?n en la misma posici?n que se han metido en mallocBuffersDatasets
313
			String name = getDataset(iDataset).getFName();
314
						
315
			for(int iBand = 0; iBand < getDataset(iDataset).getBandCount(); iBand ++) {
316
				int[] posToDraw = bandList.getBufferBandToDraw(name, iBand);
317
				if(posToDraw != null) {
318
					for(int i = 0; i < posToDraw.length; i ++) {
319
						switch(getDataType()[iDataset]) {
320
						case IBuffer.TYPE_BYTE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
321
						case IBuffer.TYPE_SHORT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
322
						case IBuffer.TYPE_INT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
323
						case IBuffer.TYPE_FLOAT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
324
						case IBuffer.TYPE_DOUBLE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
325
						}
326
					}
327
				}
328
			}
329
		}
330
	}
331
	
332
	/**
333
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
334
	 * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
335
	 * pixeles de disco. 
336
	 * @param x Posici?n X superior izquierda
337
	 * @param y Posici?n Y superior izquierda
338
	 * @param w Ancho en coordenadas reales
339
	 * @param h Alto en coordenadas reales
340
	 * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
341
	 * @param bandList
342
	 * @return Buffer de datos
343
	 */
344
	public IBuffer getWindowRaster(double x, double y, double w, double h, boolean adjustToExtent) 
345
		throws InvalidSetViewException {
346
		
347
		Extent selectedExtent = new Extent(x, y, x + w, y - h);
348

  
349
		//Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
350
		//por arriba el m?s alto y por abajo el menor y luego restandolos
351
		
352
		Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x, y));
353
		Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x + w, y - h));
354
		int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
355
		int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
356
		
357
		int mallocNBands = 0;
358
		if(bandList.getDrawableArray() != null)
359
			mallocNBands = bandList.getDrawableArray().length;
360
		else
361
			bandList.getDrawableBandsCount();
362
		
363
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
364
		
365
		//Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
366
		if(!raster.isBandSwitchable()) {
367
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0).getBandCount(), false);
368
			if(rb instanceof RasterReadOnlyHugeBuffer) {
369
				try {
370
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
371
				} catch (FileNotExistsException e) {
372
					//Esto no debe darse ya que se comprueba al hacer el open
373
				} catch (NotSupportedExtensionException e) {
374
					//Esto no debe darse ya que se comprueba al hacer el open
375
				}
376
				return rb;
377
			}
378
				
379
		}
380
					
381
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
382
			raster.assignBandToNotValid(iBand);
383
		
384
		//Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
385
		//m?s grande y salirse de los l?mites.
386
		if(!adjustToExtent)
387
			 initBufferToNoData(raster, bandList);
388
		
389
		//Reservamos memoria para los buffers por dataset
390
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
391
		for(int i = 0; i < getDatasetCount(); i++)
392
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
393
			
394
		//Mezclamos los buffers de cada dataset en un solo buffer
395
		mergeBuffers(raster, bufferDatasets, bandList);
396
							
397
		return raster;
398
	}
399
			
400
	/**
401
	 * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
402
	 * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
403
	 * el driver.
404
	 * @param minX Valor m?nimo de la X en coordenadas reales
405
	 * @param minY Valor m?nimo de la Y en coordenadas reales
406
	 * @param maxX Valor m?ximo de la X en coordenadas reales
407
	 * @param maxY Valor m?ximo de la Y en coordenadas reales
408
	 * @param bufWidth ancho del buffer lde datos
409
	 * @param bufHeight alto del buffer de datos
410
	 * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
411
	 * @param bandList
412
	 * @return Buffer de datos
413
	 */
414
	public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, 
415
									int bufWidth, int bufHeight, boolean adjustToExtent) throws InvalidSetViewException {
416
		
417
		if(	minX < ((RasterDataset)files.get(0)).getExtent().minX() || minY < ((RasterDataset)files.get(0)).getExtent().minY() ||
418
			maxX > ((RasterDataset)files.get(0)).getExtent().maxX() || maxY > ((RasterDataset)files.get(0)).getExtent().maxY())
419
				throw new InvalidSetViewException("");
420
		
421
		int mallocNBands = 0;
422
		if(bandList.getDrawableArray() != null)
423
			mallocNBands = bandList.getDrawableArray().length;
424
		else
425
			bandList.getDrawableBandsCount();
426
		
427
		IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
428
		
429
		//TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
430
		//Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
431
		/*if(!raster.isBandSwitchable()) {
432
			RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
433
			if(rb instanceof RasterReadOnlyHugeBuffer) {
434
				try {
435
					((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
436
				} catch (FileNotExistsException e) {
437
					//Esto no debe darse ya que se comprueba al hacer el open
438
				} catch (NotSupportedExtensionException e) {
439
					//Esto no debe darse ya que se comprueba al hacer el open
440
				}
441
				return rb;
442
			}
443
		}*/
444
			
445
		for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
446
			raster.assignBandToNotValid(iBand);
447
		
448
		//Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
449
		//m?s grande y salirse de los l?mites.
450
		if(!adjustToExtent)
451
			 initBufferToNoData(raster, bandList);	
452
		
453
		//Reservamos memoria para los buffers por dataset
454
		IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
455
		for(int i = 0; i < getDatasetCount(); i++)
456
			bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(minX, minY, maxX, maxY, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
457
		
458
		//Mezclamos los buffers de cada dataset en un solo buffer
459
		mergeBuffers(raster, bufferDatasets, bandList);
460
							
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff