Revision 488

View differences:

org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/distribution/distribution.xml
1
<assembly>
2
</assembly>
0 3

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/.project
1
<projectDescription>
2
  <name>org.gvsig.raster.gdal.io</name>
3
  <comment>Gdal data provider for gvSIG</comment>
4
  <projects>
5
    <project>org.gvsig.raster.cache.lib.api</project>
6
    <project>org.gvsig.raster.lib.api</project>
7
    <project>org.gvsig.raster.lib.impl</project>
8
  </projects>
9
  <buildSpec>
10
    <buildCommand>
11
      <name>org.eclipse.jdt.core.javabuilder</name>
12
    </buildCommand>
13
  </buildSpec>
14
  <natures>
15
    <nature>org.eclipse.jdt.core.javanature</nature>
16
  </natures>
17
</projectDescription>
0 18

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/DefaultGdalIOLibrary.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io;
23

  
24
import org.gvsig.fmap.dal.DALFileLibrary;
25
import org.gvsig.fmap.dal.DALLibrary;
26
import org.gvsig.raster.impl.store.AbstractRasterFileDataParameters;
27
import org.gvsig.tools.ToolsLibrary;
28
import org.gvsig.tools.library.AbstractLibrary;
29
import org.gvsig.tools.library.Library;
30
import org.gvsig.tools.library.LibraryException;
31
/**
32
 *
33
 * @author Nacho Brodin (nachobrodin@gmail.com)
34
 */
35
public class DefaultGdalIOLibrary extends AbstractLibrary {	
36

  
37
	public DefaultGdalIOLibrary() {
38
		super(DefaultGdalIOLibrary.class,Library.TYPE.IMPL);
39
		require(ToolsLibrary.class);
40
		require(DALLibrary.class);
41
		require(DALFileLibrary.class);
42
	}
43
	
44
	@Override
45
	protected void doInitialize() throws LibraryException {
46
		//RasterLibrary.wakeUp();
47
	}
48

  
49
	@Override
50
	protected void doPostInitialize() throws LibraryException {
51
		AbstractRasterFileDataParameters.registerDynClass();
52
		
53
		// Registro de los drivers de lectura
54
		GdalProvider.register();
55
		
56
		// Registro de los drivers de escritura
57
		GdalWriter.register();
58
		JpegWriter.register();
59
		PngWriter.register();
60
	}
61
}
0 62

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/GdalNative.java
1
	/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io;
23

  
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.io.IOException;
28

  
29
import org.gvsig.fmap.dal.coverage.RasterLibrary;
30
import org.gvsig.fmap.dal.coverage.RasterLocator;
31
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
32
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
33
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
34
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
35
import org.gvsig.raster.impl.datastruct.ExtentImpl;
36
import org.gvsig.raster.impl.process.RasterTask;
37
import org.gvsig.raster.impl.process.RasterTaskQueue;
38
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
39
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
40
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
41
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
42

  
43
import es.gva.cit.jgdal.Gdal;
44
import es.gva.cit.jgdal.GdalBuffer;
45
import es.gva.cit.jgdal.GdalException;
46
import es.gva.cit.jgdal.GdalRasterBand;
47
import es.gva.cit.jgdal.GeoTransform;
48
/**
49
 * Soporte 'nativo' para ficheros desde GDAL.
50
 * 
51
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
52
 * @author Nacho Brodin (nachobrodin@gmail.com)
53
 */
54
public class GdalNative extends Gdal {
55
	private String                       fileName                = null;
56
	private String                       shortName               = "";
57
	public 	GeoTransform                 trans                   = null;
58
	public int                           width                   = 0, height = 0;
59
	public double                        originX                 = 0D, originY = 0D;
60
	public String                        version                 = "";
61
	protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
62
	private int[]                        dataType                = null;
63
	DataStoreMetadata                    metadata                = null;
64
	protected boolean                    georeferenced           = true;
65
	
66
	/**
67
	 * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
68
	 * , es decir el n�mero de pixels de pantalla que tiene un pixel de imagen. Como todos
69
	 * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
70
	 * una variable. Adem�s hay que tener en cuenta que el primer y �ltimo pixel son de 
71
	 * distinto tama�o que el resto.   
72
	 */
73
	public int[]                          stepArrayX             = null;
74
	public int[]                          stepArrayY             = null;
75
	protected GdalRasterBand[]            gdalBands              = null;
76
	private double                        lastReadLine           = -1;
77
	private int                           currentFullWidth       = -1;
78
	private int                           currentFullHeight      = -1;
79
	private int                           currentViewWidth       = -1;
80
	private int                           currentViewHeight      = -1;
81
	private double                        currentViewX           = 0D;
82
	private double                        viewportScaleX         = 0D;
83
	private double                        viewportScaleY         = 0D;
84
	private double                        stepX                  = 0D;
85
	private double                        stepY                  = 0D;
86
	public boolean                        isSupersampling        = false;
87
	private boolean                       open                   = false;
88
	/**
89
	 * Estado de transparencia del raster.
90
	 */
91
	DataStoreTransparency                 fileTransparency       = null;
92
	DataStoreColorTable                   palette                = null;
93
	DataStoreColorInterpretation          colorInterpr           = null;
94
	AffineTransform                       ownTransformation      = null;
95
	AffineTransform                       externalTransformation = new AffineTransform();
96
	
97
	
98
	/**
99
	 * Overview usada en el ?ltimo setView
100
	 */
101
	int currentOverview = -1;
102
	
103
	
104
	public GdalNative(String fName) throws GdalException, IOException {
105
		super();
106
		init(fName);
107
	}
108
	
109
	private void init(String fName) throws GdalException, IOException {
110
		fileName = fName;
111
		open(fName, GA_ReadOnly);
112
		open = true;
113
		if (getPtro() == -1)
114
			throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
115
//		ext = RasterUtilities.getExtensionFromFileName(fName);
116
		width = getRasterXSize();
117
		height = getRasterYSize();
118
		int[] dt = new int[getRasterCount()];
119
		for (int i = 0; i < getRasterCount(); i++)
120
			dt[i] = this.getRasterBand(i + 1).getRasterDataType();
121
		setDataType(dt);
122
		shortName = getDriverShortName();
123
		fileTransparency = new DataStoreTransparency();
124
		colorInterpr = new DataStoreColorInterpretation();
125
		metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
126

  
127
		// Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
128
		// nos sirve para saber que banda de la imagen va asignada a cada banda de
129
		// visualizaci?n (ARGB)
130
		colorInterpr.initColorInterpretation(getRasterCount());
131
		metadata.initNoDataByBand(getRasterCount());
132
		for (int i = 0; i < getRasterCount(); i++) {
133
			GdalRasterBand rb = getRasterBand(i + 1);
134
			String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
135
			metadata.setNoDataValue(i, (rb.getRasterNoDataValue() == -9999.0) ? RasterLibrary.defaultNoDataValue : rb.getRasterNoDataValue());
136
			metadata.setNoDataEnabled(rb.existsNoDataValue());
137
			colorInterpr.setColorInterpValue(i, colorInt);
138
			if (colorInt.equals("Alpha"))
139
				fileTransparency.setTransparencyBand(i);
140

  
141
			if (rb.getRasterColorTable() != null && palette == null) {
142
				palette = new DataStoreColorTable();
143
				palette.createPaletteFromGdalColorTable(rb.getRasterColorTable());
144
//				fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
145
			}
146
		}
147
		fileTransparency.setTransparencyByPixelFromMetadata(metadata);
148

  
149
		try {
150
			trans = getGeoTransform();
151

  
152
			boolean isCorrect = false;
153
			for (int i = 0; i < trans.adfgeotransform.length; i++)
154
				if (trans.adfgeotransform[i] != 0)
155
					isCorrect = true;
156
			if (!isCorrect)
157
				throw new GdalException("");
158

  
159
			ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
160
			externalTransformation = (AffineTransform) ownTransformation.clone();
161
			currentFullWidth = width;
162
			currentFullHeight = height;
163

  
164
			this.georeferenced = true;
165
		} catch (GdalException exc) {
166
			// Transformaci�n para ficheros sin georreferenciaci�n. Se invierte la Y
167
			// ya que las WC decrecen de
168
			// arriba a abajo y los pixeles crecen de arriba a abajo
169
			ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
170
			externalTransformation = (AffineTransform) ownTransformation.clone();
171
			currentFullWidth = width;
172
			currentFullHeight = height;
173
			this.georeferenced = false;
174
		}
175
	}
176
	
177
	/**
178
	 * Returns true if this provider is open and false if don't
179
	 * @return
180
	 */
181
	public boolean isOpen() {
182
		return open;
183
	}
184
	
185
	/*
186
	 * (non-Javadoc)
187
	 * @see es.gva.cit.jgdal.Gdal#close()
188
	 */
189
	public void close() throws GdalException {
190
		open = false;
191
		super.close();
192
	}
193
	
194
	/**
195
	 * Obtiene el flag que informa de si el raster tiene valor no data o no.
196
	 * Consultar� todas las bandas del mismo y si alguna tiene valor no data
197
	 * devuelve true sino devolver� false.
198
	 * @return true si tiene valor no data y false si no lo tiene
199
	 * @throws GdalException
200
	 */
201
	public boolean existsNoDataValue() throws GdalException {
202
		for (int i = 0; i < getRasterCount(); i++) {
203
			GdalRasterBand rb = getRasterBand(i + 1);
204
			if (rb.existsNoDataValue())
205
				return true;
206
		}
207
		return false;
208
	}
209
	
210
	/**
211
	 * Obtiene el flag que informa de si el raster tiene valor no data o no
212
	 * en una banda concreta.
213
	 * @return true si tiene valor no data en esa banda y false si no lo tiene
214
	 * @param band Posici�n de la banda a consultar (0..n)
215
	 * @throws GdalException
216
	 */
217
	public boolean existsNoDataValue(int band) throws GdalException {
218
		GdalRasterBand rb = getRasterBand(band + 1);
219
		return rb.existsNoDataValue();
220
	}
221

  
222
	/**
223
	 * Devuelve el valor NoData en caso de existir, sino existe devuelve null.
224
	 * @return
225
	 */
226
	public double getNoDataValue() {
227
		if (metadata == null)
228
			return RasterLibrary.defaultNoDataValue;
229

  
230
		if (metadata.getNoDataValue().length == 0)
231
			return RasterLibrary.defaultNoDataValue;
232

  
233
		return metadata.getNoDataValue()[0];
234
	}
235

  
236
	/**
237
	 * Asigna el tipo de dato
238
	 * @param dt entero que representa el tipo de dato
239
	 */
240
	public void setDataType(int[] dt) { 
241
		dataType = dt; 
242
	}
243
	
244
	/**
245
	 * Obtiene el tipo de dato
246
	 * @return entero que representa el tipo de dato
247
	 */
248
	public int[] getDataType() { 
249
		return dataType; 
250
	}
251
	
252
	/**
253
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
254
	 * del punto real.
255
	 * Supone rasters no girados
256
	 * @param pt	punto en coordenadas del punto real
257
	 * @return	punto en coordenadas del raster
258
	 */
259
	public Point2D worldToRasterWithoutRot(Point2D pt) {
260
		Point2D p = new Point2D.Double();
261
		AffineTransform at = new AffineTransform(	externalTransformation.getScaleX(), 0, 
262
													0, externalTransformation.getScaleY(), 
263
													externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
264
		try {
265
			at.inverseTransform(pt, p);
266
		} catch (NoninvertibleTransformException e) {
267
			return pt;
268
		}
269
		return p;
270
	}
271
		
272
	/**
273
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
274
	 * del punto real.
275
	 * Supone rasters no girados
276
	 * @param pt	punto en coordenadas del punto real
277
	 * @return	punto en coordenadas del raster
278
	 */
279
	public Point2D worldToRaster(Point2D pt) {
280
		Point2D p = new Point2D.Double();
281
		try {
282
			externalTransformation.inverseTransform(pt, p);
283
		} catch (NoninvertibleTransformException e) {
284
			return pt;
285
		}
286
		return p;
287
	}
288
	
289
	/**
290
	 * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
291
	 * reales. 
292
	 * @param pt Punto en coordenadas reales
293
	 * @return Punto en coordenadas pixel.
294
	 */
295
	public Point2D rasterToWorld(Point2D pt) {
296
		Point2D p = new Point2D.Double();
297
		externalTransformation.transform(pt, p);
298
		return p;
299
	}
300
	
301
	/**
302
	 * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
303
	 * viewPortScale, currentFullWidth y currentFulHeight
304
	 * @param coordenada pixel expresada en double que indica la posici�n superior izquierda
305
	 * @throws GdalException
306
	 */
307
	private void calcOverview(Point2D tl, Point2D br) throws GdalException {
308
		gdalBands[0] = getRasterBand(1);
309
		currentOverview = -1;
310
		if (gdalBands[0].getOverviewCount() > 0) {
311
			GdalRasterBand ovb = null;
312
			for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
313
				ovb = gdalBands[0].getOverview(i);
314
				if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
315
					currentOverview = i;
316
					viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
317
					viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
318
					stepX = 1D / viewportScaleX;
319
					stepY = 1D / viewportScaleY;
320
					currentFullWidth = ovb.getRasterBandXSize();
321
					currentFullHeight = ovb.getRasterBandYSize();
322
					currentViewX = Math.min(tl.getX(), br.getX());
323
					lastReadLine = Math.min(tl.getY(), br.getY());
324
					break;
325
				}
326
			}
327
		}
328
	}
329
	
330
	public void setView(double dWorldTLX, double dWorldTLY,
331
						double dWorldBRX, double dWorldBRY,
332
						int nWidth, int nHeight) throws GdalException {
333
		currentFullWidth = width;
334
		currentFullHeight = height;
335
		Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
336
		Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
337
		// Calcula cual es la primera l�nea a leer;
338
		currentViewWidth = nWidth;
339
		currentViewHeight = nHeight;
340
//		wcWidth = Math.abs(br.getX() - tl.getX());
341

  
342
		currentViewX = Math.min(tl.getX(), br.getX());
343

  
344
		viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
345
		viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
346
		stepX = 1D / viewportScaleX;
347
		stepY = 1D / viewportScaleY;
348

  
349
		lastReadLine = Math.min(tl.getY(), br.getY());
350
		
351
		//Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
352

  
353
		// calcula el overview a usar
354
		gdalBands = new GdalRasterBand[4];
355
		calcOverview(tl, br);
356

  
357
		// Selecciona las bandas y los overviews necesarios
358
		/*gdalBands[0] = getRasterBand(rBandNr);
359
		gdalBands[1] = gdalBands[0]; 
360
		gdalBands[2] = gdalBands[1]; 
361

  
362
		if(getRasterCount() >= 2) {
363
			gdalBands[1] = getRasterBand(gBandNr);
364
			gdalBands[2] = gdalBands[1]; 
365
		}
366
		if(this.getRasterCount() >= 3) 
367
			gdalBands[2] = getRasterBand(bBandNr);
368
		if(colorInterpr.isAlphaBand())
369
			gdalBands[3] = getRasterBand(aBandNr);			
370

  
371
		assignDataTypeFromGdalRasterBands(gdalBands);
372

  
373
		if (currentOverview > 0) {
374
			gdalBands[0] = gdalBands[0].getOverview(currentOverview);
375
			if(getRasterCount() >= 2) {
376
				gdalBands[1] = gdalBands[1].getOverview(currentOverview);
377
			}
378
			if(this.getRasterCount() >= 3) 
379
				gdalBands[2] = gdalBands[2].getOverview(currentOverview);
380
			if(colorInterpr.isAlphaBand())
381
				gdalBands[3] = gdalBands[3].getOverview(currentOverview);			
382

  
383
		}*/
384
	}
385
	
386
	/**
387
	 * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n�mero de bandas solicitado.
388
	 * @param nbands N�mero de bandas solicitado.
389
	 * @throws GdalException
390
	 */
391
	public void selectGdalBands(int nbands) throws GdalException {
392
		gdalBands = new GdalRasterBand[nbands];
393
		// Selecciona las bandas y los overviews necesarios
394
		gdalBands[0] = getRasterBand(1);
395
		for (int i = 0; i < nbands; i++)
396
			gdalBands[i] = gdalBands[0];
397

  
398
		assignDataTypeFromGdalRasterBands(gdalBands);
399
//		setDataType(gdalBands[0].getRasterDataType());
400

  
401
		for (int i = 2; i <= nbands; i++) {
402
			if (getRasterCount() >= i) {
403
				gdalBands[i - 1] = getRasterBand(i);
404
				for (int j = i; j < nbands; j++)
405
					gdalBands[j] = gdalBands[i - 1];
406
			}
407
		}
408

  
409
		if (currentOverview > 0) {
410
			gdalBands[0] = gdalBands[0].getOverview(currentOverview);
411
			for (int i = 2; i <= nbands; i++) {
412
				if (getRasterCount() >= i)
413
					gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
414
			}
415
		}
416
	}
417
		
418
	int lastY = -1;
419
	
420
	/**
421
	 * Lee una l�nea de bytes
422
	 * @param line Buffer donde se cargan los datos
423
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
424
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
425
	 * por la izquierda a mitad de pixel
426
	 * @param gdalBuffer Buffer con la l�nea de datos original
427
	 */
428
	private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
429
		double j = 0D;
430
		int i = 0;
431
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
432
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
433
				line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
434
			}
435
		}
436
	}
437
	
438
	/**
439
	 * Lee una l�nea de shorts
440
	 * @param line Buffer donde se cargan los datos
441
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
442
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
443
	 * por la izquierda a mitad de pixel
444
	 * @param gdalBuffer Buffer con la l�nea de datos original
445
	 */
446
	private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
447
		double j = 0D;
448
		int i = 0;
449
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
450
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
451
				line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
452
			}
453
		}
454
	}
455

  
456
	/**
457
	 * Lee una l�nea de ints
458
	 * @param line Buffer donde se cargan los datos
459
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
460
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
461
	 * por la izquierda a mitad de pixel
462
	 * @param gdalBuffer Buffer con la l�nea de datos original
463
	 */
464
	private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
465
		double j = 0D;
466
		int i = 0;
467
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
468
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
469
				line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
470
			}
471
		}
472
	}
473

  
474
	/**
475
	 * Lee una l�nea de float
476
	 * @param line Buffer donde se cargan los datos
477
	 * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
478
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
479
	 * por la izquierda a mitad de pixel
480
	 * @param gdalBuffer Buffer con la l�nea de datos original
481
	 */
482
	private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
483
		double j = 0D;
484
		int i = 0;
485
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
486
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
487
				line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
488
			}
489
		}
490
	}
491
	
492
	/**
493
	 * Lee una l�nea de doubles
494
	 * @param line Buffer donde se cargan los datos
495
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
496
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
497
	 * por la izquierda a mitad de pixel
498
	 * @param gdalBuffer Buffer con la l�nea de datos original
499
	 */
500
	private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
501
		double j = 0D;
502
		int i = 0;
503
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
504
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
505
				line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
506
			}
507
		}
508
	}
509

  
510
	/**
511
	 * Lee una l�nea completa del raster y devuelve un array del tipo correcto. Esta funci�n es util
512
	 * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
513
	 * @param nLine N�mero de l�nea a leer
514
	 * @param band Banda requerida
515
	 * @return Object que es un array unidimendional del tipo de datos del raster
516
	 * @throws GdalException
517
	 */
518
	public Object readCompleteLine(int nLine, int band) throws GdalException {
519
		GdalRasterBand gdalBand = super.getRasterBand(band + 1);
520
		GdalBuffer gdalBuf = null;
521

  
522
		gdalBuf = gdalBand.readRaster(0, nLine, getRasterXSize(), 1, getRasterXSize(), 1, dataType[band]);
523

  
524
		if (dataType[band] == GDT_Byte)
525
			return gdalBuf.buffByte;
526

  
527
		if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
528
			return gdalBuf.buffShort;
529

  
530
		if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
531
			return gdalBuf.buffInt;
532

  
533
		if (dataType[band] == GDT_Float32)
534
			return gdalBuf.buffFloat;
535

  
536
		if (dataType[band] == GDT_Float64)
537
			return gdalBuf.buffDouble;
538

  
539
		if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
540
				dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
541
			return null;
542
		
543
		return null;
544
	}
545
	
546
	/**
547
	 * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci�n es util
548
	 * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
549
	 * @param nLine N�mero de l�nea a leer
550
	 * @param band Banda requerida
551
	 * @return Object que es un array unidimendional del tipo de datos del raster
552
	 * @throws GdalException
553
	 */
554
	public Object readBlock(int pos, int blockHeight) throws GdalException, ProcessInterruptedException {
555
		bBandNr = super.getRasterCount();
556
		int nX = getRasterXSize();
557

  
558
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
559
				
560
		GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
561
		for (int iBand = 0; iBand < gdalBand.length; iBand++) 
562
			gdalBand[iBand] = super.getRasterBand(iBand + 1);
563
				
564
		GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
565
				
566
		if (dataType[0] == GDT_Byte) {
567
			byte[][][] buf = new byte[bBandNr][blockHeight][getRasterXSize()];
568
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
569
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
570
				for (int iRow = 0; iRow < blockHeight; iRow++) {
571
					for (int iCol = 0; iCol < nX; iCol++) 
572
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * nX + iCol];
573
					if(task.getEvent() != null)
574
						task.manageEvent(task.getEvent());
575
				}
576
			}	
577
			return buf;
578
		} else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
579
			short[][][] buf = new short[bBandNr][blockHeight][getRasterXSize()];
580
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
581
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
582
				for (int iRow = 0; iRow < blockHeight; iRow++) {
583
					for (int iCol = 0; iCol < nX; iCol++) 
584
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * nX + iCol];
585
					if(task.getEvent() != null)
586
						task.manageEvent(task.getEvent());
587
				}
588
			}	
589
			return buf;
590
		} else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
591
			int[][][] buf = new int[bBandNr][blockHeight][getRasterXSize()];
592
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
593
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
594
				for (int iRow = 0; iRow < blockHeight; iRow++) { 
595
					for (int iCol = 0; iCol < nX; iCol++)
596
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * nX + iCol];
597
					if(task.getEvent() != null)
598
						task.manageEvent(task.getEvent());
599
				}
600
			}	
601
			return buf;
602
		} else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
603
			float[][][] buf = new float[bBandNr][blockHeight][getRasterXSize()];
604
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
605
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
606
				for (int iRow = 0; iRow < blockHeight; iRow++) {
607
					for (int iCol = 0; iCol < nX; iCol++)
608
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * nX + iCol];
609
					if(task.getEvent() != null)
610
						task.manageEvent(task.getEvent());
611
				}
612
			}	
613
			return buf;
614
		} else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
615
			double[][][] buf = new double[bBandNr][blockHeight][getRasterXSize()];
616
			for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
617
				gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
618
				for (int iRow = 0; iRow < blockHeight; iRow++) {
619
					for (int iCol = 0; iCol < nX; iCol++) 
620
						buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * nX + iCol];
621
					if(task.getEvent() != null)
622
						task.manageEvent(task.getEvent());
623
				}
624
			}		
625
			return buf;
626
		}
627
				
628
			return null;
629
	}
630
	
631
	/**
632
	 * Lectura de una l�nea de datos.
633
	 * @param line
634
	 * @throws GdalException
635
	 */
636
	public void readLine(Object line) throws GdalException {
637
		int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
638
		int x = (int) (currentViewX);
639
		int y = (int) (lastReadLine);
640
		GdalBuffer r = null, g = null, b = null;
641
		GdalBuffer a = new GdalBuffer();
642

  
643
		while(y >= gdalBands[0].getRasterBandYSize())
644
			y--;
645

  
646
		if (x+w > gdalBands[0].getRasterBandXSize()) 
647
			w = gdalBands[0].getRasterBandXSize()-x;
648

  
649
		if(gdalBands[0].getRasterColorTable() != null) {
650
			palette = new DataStoreColorTable();
651
			palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
652
			r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
653
		} else {
654
			a.buffByte = new byte[w];
655
			r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
656
			g = b = r;
657
			if (getRasterCount() > 1 && gdalBands[1] != null)
658
				g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
659
			if (getRasterCount() > 2 && gdalBands[2] != null)
660
				b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
661
		}
662

  
663
		lastReadLine += stepY;
664

  
665
		double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
666
		GdalBuffer[] bands = {r, g, b};
667

  
668
		if (dataType[0] == GDT_Byte)
669
			readLine((byte[][])line, initOffset, bands);
670
		else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
671
			readLine((short[][])line, initOffset, bands);
672
		else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
673
			readLine((int[][])line, initOffset, bands);
674
		else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
675
			readLine((float[][])line, initOffset, bands);
676
		else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
677
			readLine((double[][])line, initOffset, bands);
678

  
679
		return;
680
	}
681
			
682
	/**
683
	 * Cuando se hace una petici�n de carga de buffer la extensi�n pedida puede
684
	 * estar ajustada a la extensi�n del raster o no estarlo. En caso de no
685
	 * estarlo los pixeles del buffer que caen fuera de la extensi�n del raster
686
	 * tendr�n valor de NoData. Esta funci�n calcula en que pixel del buffer hay
687
	 * que empezar a escribir en caso de que este sea mayor que los datos a leer.
688
	 * 
689
	 * @param dWorldTLX Posici�n X superior izquierda en coord reales
690
	 * @param dWorldTLY Posici�n Y superior izquierda en coord reales
691
	 * @param dWorldBRX Posici�n X inferior derecha en coord reales
692
	 * @param dWorldBRY Posici�n Y inferior derecha en coord reales
693
	 * @param nWidth Ancho en pixeles del buffer
694
	 * @param nHeight Alto en pixeles del buffer
695
	 * @return desplazamiento dentro del buffer en X e Y
696
	 */ 
697
	private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
698
		Extent imageExtent = getExtentWithoutRot();
699
		Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
700
		if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
701
			Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
702
			Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
703
			Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
704
			//    		Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
705
			//Ese es el ancho y alto q tendr�a el buffer en caso de haberse ajustado
706
			int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
707
			int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
708

  
709
			stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
710
			stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
711
			stpBuffer[2] = stpBuffer[0] + w; 
712
			stpBuffer[3] = stpBuffer[1] + h;
713
			return new int[]{w, h};
714
		}
715
		return new int[]{nWidth, nHeight};
716
	}
717
	
718
	/**
719
	 * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
720
	 * @param buf Buffer donde se almacenan los datos
721
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
722
	 * @param dWorldTLX Posici�n X superior izquierda en coord reales
723
	 * @param dWorldTLY Posici�n Y superior izquierda en coord reales
724
	 * @param dWorldBRX Posici�n X inferior derecha en coord reales
725
	 * @param dWorldBRY Posici�n Y inferior derecha en coord reales
726
	 * @param nWidth Ancho en pixeles del buffer
727
	 * @param nHeight Alto en pixeles del buffer
728
	 * @throws GdalException
729
	 */
730
	public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
731
			int nWidth, int nHeight, boolean adjustToExtent) throws GdalException, ProcessInterruptedException {
732
		Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
733
		setView(ulx, uly, lrx, lry, nWidth, nHeight);
734
		Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
735
		Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
736

  
737
		if(tl.getX() > br.getX())
738
			tl.setLocation(tl.getX() - 1, tl.getY());
739
		else
740
			br.setLocation(br.getX() - 1, br.getY());
741
		
742
		if(tl.getY() > br.getY())
743
			tl.setLocation(tl.getX(), tl.getY() - 1);
744
		else
745
			br.setLocation(br.getX(), br.getY() - 1);
746
		
747
		if(gdalBands.length == 0)
748
			return;
749

  
750
		selectGdalBands(/*buf.getBandCount()*/getRasterCount());
751

  
752
		int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
753
		int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
754

  
755
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
756
		//Si el buffer no se ajusta al extent entonces calculamos en que posici�n comienza a escribirse dentro del buffer
757
		//ya que lo que cae fuera ser�n valores NoData
758
		if(!adjustToExtent){
759
			int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
760
			if(x < 0)
761
				x  = 0;
762
			if(y < 0)
763
				y  = 0;
764
			readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer);
765
			return;
766
		}
767

  
768
		readData(buf, bandList, x, y, nWidth, nHeight, nWidth, nHeight, 0, 0, stpBuffer);
769
	}
770
			
771
	/**
772
	 * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m�todo lee la
773
	 * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
774
	 * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
775
	 * Esto se hace m�s evidente cuando supersampleamos en la petici�n, es decir el buffer de de 
776
	 * mayor tama�o que el n�mero de pixels solicitado.
777
	 * 
778
	 * Para resolver esto escribiremos con la funci�n readRaster los datos sobre un buffer mayor 
779
	 * que el solicitado. Despu�s calcularemos el desplazamiento en pixels dentro de este buffer 
780
	 * de mayor tama�o hasta llegar a la coordenada real donde comienza la petici�n real que ha
781
	 * hecho el usuario. Esto es as� porque cuando supersampleamos no queremos los pixeles del 
782
	 * raster de disco completos sino que en los bordes del buffer quedan cortados.  
783
	 *  
784
	 * @param buf Buffer donde se almacenan los datos
785
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
786
	 * @param dWorldTLX Posici�n X superior izquierda en coord reales
787
	 * @param dWorldTLY Posici�n Y superior izquierda en coord reales
788
	 * @param dWorldBRX Posici�n X inferior derecha en coord reales
789
	 * @param dWorldBRY Posici�n Y inferior derecha en coord reales
790
	 * @param nWidth Ancho en pixeles de la petici�n
791
	 * @param nHeight Alto en pixeles de la petici�n
792
	 * @param bufWidth Ancho del buffer
793
	 * @param bufHeight Alto del buffer
794
	 * @throws GdalException
795
	 */
796
	public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
797
										double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent) throws GdalException, ProcessInterruptedException {
798
		Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
799
		setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
800
		Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
801
		Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
802
		ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
803
		lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
804
		ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
805
		lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
806
		
807
		/*if(tl.getX() > br.getX())
808
			tl.setLocation(tl.getX() - 1, tl.getY());
809
		else
810
			br.setLocation(br.getX() - 1, br.getY());
811
		
812
		if(tl.getY() > br.getY())
813
			tl.setLocation(tl.getX(), tl.getY() - 1);
814
		else
815
			br.setLocation(br.getX(), br.getY() - 1);*/
816
		
817
		adjustPoints(ul, lr);
818
		
819
		if(gdalBands.length == 0)
820
			return;
821
		
822
		selectGdalBands(/*buf.getBandCount()*/getRasterCount());
823
				
824
		int x = (int) Math.min(ul.getX(), lr.getX());
825
		int y = (int) Math.min(ul.getY(), lr.getY());
826
		//int endX = (int) Math.ceil(Math.max(br.getX(), tl.getX()));
827
		//int endY = (int) Math.ceil(Math.max(br.getY(), tl.getY()));
828

  
829
		int stpX = 0;
830
		int stpY = 0;
831
				
832
		/*if(bufWidth > Math.ceil(nWidth)){
833
			stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
834
			bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
835
		}
836
		if(bufHeight > Math.ceil(nHeight)){
837
			stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
838
			bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
839
		}
840

  
841
		nWidth = (int)Math.abs(endX - x);
842
		nHeight = (int)Math.abs(endY - y);*/
843

  
844
		nWidth = (nWidth * currentFullWidth) / width;
845
		nHeight = (nHeight * currentFullHeight) / height;
846
		x = (int)(((long)x * (long)currentFullWidth) / (long)width);
847
		y = (int) (((long)y * (long)currentFullHeight) / (long)height);
848

  
849
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
850
		//Si el buffer no se ajusta al extent entonces calculamos en que posici�n comienza a escribirse dentro del buffer
851
		//ya que lo que cae fuera ser�n valores NoData
852
		if(!adjustToExtent){
853
			int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
854
			if(x < 0)
855
				x  = 0;
856
			if(y < 0)
857
				y  = 0;
858
			stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / nWidth);
859
			stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / nHeight);
860
			stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / nWidth);
861
			stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / nHeight);
862
			bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
863
			bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
864
			readData(buf, bandList, x, y, wh[0], wh[1], bufWidth, bufHeight, 0, 0, stpBuffer);
865
			return;
866
		}
867

  
868
		if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
869
			nWidth = gdalBands[0].getRasterBandXSize() - x;
870

  
871
		if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
872
			nHeight = gdalBands[0].getRasterBandYSize() - y;
873

  
874
		readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer);
875
	}
876
	
877
	private void adjustPoints(Point2D ul, Point2D lr) {
878
		double a = (ul.getX() - (int)ul.getX());
879
		double b = (ul.getY() - (int)ul.getY());
880
		ul.setLocation(	(a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
881
						(b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
882
		lr.setLocation(	(a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
883
						(b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
884
	}
885

  
886
	/**
887
	 * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
888
	 * @param buf Buffer donde se almacenan los datos
889
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
890
	 * @param x Posici�n X en pixeles
891
	 * @param y Posici�n Y en pixeles
892
	 * @param w Ancho en pixeles
893
	 * @param h Alto en pixeles
894
	 * @throws GdalException
895
	 */
896
	public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h) 
897
		throws GdalException, ProcessInterruptedException {
898
		gdalBands = new GdalRasterBand[getRasterCount()];
899
		isSupersampling = false;
900
		if(gdalBands.length == 0)
901
			return;
902
		
903
		// Selecciona las bandas
904
		gdalBands[0] = getRasterBand(1);
905
		
906
		for(int iBand = 1; iBand < gdalBands.length; iBand++)
907
			gdalBands[iBand] = getRasterBand(iBand + 1);
908
		
909
		assignDataTypeFromGdalRasterBands(gdalBands);
910
		
911
		int[] stepBuffer = new int[]{0, 0, w, h};
912
		readData(buf, bandList, x, y, x + w, y + h, w, h, 0, 0, stepBuffer);
913
		//int yMax = y + h;
914
		//readDataByLine(buf, bandList, x, y, w, yMax);
915
	}
916
	
917
	/**
918
	 * Lee una ventana de datos con resampleo a partir de coordenadas en pixeles. Este m�todo lee la
919
	 * ventana de una vez cargando los datos de un golpe en el buffer.
920
	 * @param buf Buffer donde se almacenan los datos
921
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
922
	 * @param x Posici�n X en pixeles
923
	 * @param y Posici�n Y en pixeles
924
	 * @param w Ancho en pixeles
925
	 * @param h Alto en pixeles
926
	 * @param bufWidth Ancho del buffer
927
	 * @param bufHeight Alto del buffer
928
	 * @throws GdalException
929
	 */
930
	public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h, int bufWidth, int bufHeight) throws GdalException, ProcessInterruptedException {
931
		gdalBands = new GdalRasterBand[getRasterCount()];
932
		
933
		if(gdalBands.length == 0)
934
			return;
935
		
936
		// Selecciona las bandas
937
		gdalBands[0] = getRasterBand(1);
938
		
939
		for(int iBand = 1; iBand < gdalBands.length; iBand++)
940
			gdalBands[iBand] = getRasterBand(iBand + 1);
941
		
942
		assignDataTypeFromGdalRasterBands(gdalBands);
943
		
944
		int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
945
		readData(buf, bandList, x, y, w, h, bufWidth, bufHeight, 0, 0, stpBuffer);
946
	}
947
	
948
	/**
949
	 * Asigna el tipo de datos de las bandas a partir de una lista de GdalRasterBands
950
	 * @param gdalBands
951
	 * @throws GdalException
952
	 */
953
	private void assignDataTypeFromGdalRasterBands(GdalRasterBand[] gdalBands) throws GdalException {
954
		int[] dt = new int[gdalBands.length];
955
		for (int i = 0; i < gdalBands.length; i++) {
956
			if(gdalBands[i] != null)
957
				dt[i] = gdalBands[i].getRasterDataType();
958
		}
959
		setDataType(dt);
960
	}
961
		
962
	/**
963
	 * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci�n es usuada por
964
	 * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
965
	 * @param buf Buffer donde se almacenan los datos
966
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
967
	 * @param x Posici�n X en pixeles
968
	 * @param y Posici�n Y en pixeles
969
	 * @param w Ancho en pixeles
970
	 * @param h Alto en pixeles
971
	 * @param bufWidth Ancho del buffer
972
	 * @param bufHeight Alto del buffer
973
	 * @param stepX Desplazamiento en pixeles en X a partir de la posici�n x. Este desplazamiento es util cuando hay un 
974
	 * supersampleo ya que puede ser que de los pixeles que est�n en el borde izquierdo de la petici�n solo queramos una
975
	 * parte de ellos. 
976
	 * @param stepY Desplazamiento en pixeles en Y a partir de la posici�n y. Este desplazamiento es util cuando hay un 
977
	 * supersampleo ya que puede ser que de los pixeles que est�n en el borde superior de la petici�n solo queramos una
978
	 * parte de ellos.
979
	 * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
980
	 * de fin de buffer. Este par�metro indica el desplazamiento desde el inicio del buffer y la posici�n final.
981
	 * <UL>
982
	 * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
983
	 * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
984
	 * <LI>stepBuffer[2]:Posici�n X final</LI>
985
	 * <LI>stepBuffer[3]:Posici�n Y final</LI>
986
	 * </UL>
987
	 * @throws GdalException
988
	 */
989
	private void readData(Buffer buf, BandList bandList, int x, int y, int w, int h, 
990
			int bufWidth, int bufHeight, int stpX, int stpY, int[] stepBuffer) throws GdalException, ProcessInterruptedException {
991
		
992
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString()); 
993
		
994
		GdalBuffer gdalBuf = null;
995
		for(int iBand = 0; iBand < gdalBands.length; iBand++) {
996
			int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
997
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
998
				continue;	
999
			int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
1000
			int pos = init;
1001
			gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType[iBand]);
1002
			if(dataType[iBand] == Gdal.GDT_Byte){
1003
				for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
1004
					pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1005
					for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++) {
1006
						for (int i = 0; i < drawableBands.length; i++) 
1007
							buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1008
						pos ++;
1009
					}
1010
					if(task.getEvent() != null)
1011
						task.manageEvent(task.getEvent());
1012
				}
1013
			}else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)){
1014
				for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1015
					pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1016
					for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1017
						for (int i = 0; i < drawableBands.length; i++)
1018
							buf.setElem(line, col, drawableBands[i], gdalBuf.buffShort[pos]);
1019
						pos ++;
1020
					}
1021
					if(task.getEvent() != null)
1022
						task.manageEvent(task.getEvent());
1023
				}
1024
			}else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)){
1025
				for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1026
					pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1027
					for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1028
						for (int i = 0; i < drawableBands.length; i++)
1029
							buf.setElem(line, col, drawableBands[i], gdalBuf.buffInt[pos]);
1030
						pos ++;
1031
					}
1032
					if(task.getEvent() != null)
1033
						task.manageEvent(task.getEvent());
1034
				}
1035
			}else if(dataType[iBand] == Gdal.GDT_Float32){
1036
				for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1037
					pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1038
					for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1039
						for (int i = 0; i < drawableBands.length; i++)
1040
							buf.setElem(line, col, drawableBands[i], gdalBuf.buffFloat[pos]);
1041
						pos ++;
1042
					}
1043
					if(task.getEvent() != null)
1044
						task.manageEvent(task.getEvent());
1045
				}
1046
			}else if(dataType[iBand] == Gdal.GDT_Float64){
1047
				for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1048
					pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1049
					for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1050
						for (int i = 0; i < drawableBands.length; i++)
1051
							buf.setElem(line, col, drawableBands[i], gdalBuf.buffDouble[pos]);
1052
						pos ++;
1053
					}
1054
					if(task.getEvent() != null)
1055
						task.manageEvent(task.getEvent());
1056
				}
1057
			}
1058
		}
1059
	}
1060
	
1061
	/**
1062
	 * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci�n es usuada por
1063
	 * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1064
	 * @param buf Buffer donde se almacenan los datos
1065
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1066
	 * @param x Posici�n X en pixeles
1067
	 * @param y Posici�n Y en pixeles
1068
	 * @param w Ancho en pixeles
1069
	 * @param yMax altura m�xima de y
1070
	 * @throws GdalException
1071
	 */
1072
	@SuppressWarnings("unused")
1073
	private void readDataByLine(Buffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, ProcessInterruptedException {
1074
		GdalBuffer gdalBuf = null;
1075
		int rasterBufLine;
1076
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
1077
		
1078
		for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1079
			int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
1080
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1081
				continue;	
1082
			if(dataType[iBand] == Gdal.GDT_Byte) {
1083
				for (int line = y; line < yMax; line++) {
1084
					gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1085
					rasterBufLine = line - y;
1086
					for (int i = 0; i < drawableBands.length; i++) {
1087
						buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[i]);
1088
					}
1089
					if(task.getEvent() != null)
1090
						task.manageEvent(task.getEvent());
1091
				}
1092
			}else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1093
				for (int line = y; line < yMax; line++) {
1094
					gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1095
					rasterBufLine = line - y;
1096
					for (int i = 0; i < drawableBands.length; i++) {
1097
						buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[i]);
1098
					}
1099
					if(task.getEvent() != null)
1100
						task.manageEvent(task.getEvent());
1101
				}
1102
			}else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1103
				for (int line = y; line < yMax; line++) {
1104
					gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1105
					rasterBufLine = line - y;
1106
					for (int i = 0; i < drawableBands.length; i++) {
1107
						buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[i]);
1108
					}
1109
					if(task.getEvent() != null)
1110
						task.manageEvent(task.getEvent());
1111
				}
1112
			}else if(dataType[iBand] == Gdal.GDT_Float32){
1113
				for (int line = y; line < yMax; line++) {
1114
					gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1115
					rasterBufLine = line - y;
1116
					for (int i = 0; i < drawableBands.length; i++) {
1117
						buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[i]);
1118
					}
1119
					if(task.getEvent() != null)
1120
						task.manageEvent(task.getEvent());
1121
				}
1122
			}else if(dataType[iBand] == Gdal.GDT_Float64){
1123
				for (int line = y; line < yMax; line++) {
1124
					gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1125
					rasterBufLine = line - y;
1126
					for (int i = 0; i < drawableBands.length; i++) {
1127
						buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[i]);
1128
					}
1129
					if(task.getEvent() != null)
1130
						task.manageEvent(task.getEvent());
1131
				}
1132
			}
1133
		}
1134
	}
1135
	
1136
	/**
1137
	 * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1138
	 * por par�metro
1139
	 * @param x Coordenada X del pixel
1140
	 * @param y Coordenada Y del pixel
1141
	 * @return Array de Object donde cada posici�n representa una banda y el valor ser� Integer
1142
	 * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1143
	 */
1144
	public Object[] getData(int x, int y) {
1145
		try {
1146
			Object[] data = new Object[getRasterCount()];
1147
			for(int i = 0; i < getRasterCount(); i++){
1148
				GdalRasterBand rb = getRasterBand(i + 1);
1149
				GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1150
				switch(dataType[i]){
1151
				case 0:	break;									//Sin tipo
1152
				case 1:	data[i] = new Integer(r.buffByte[0]); 	//Buffer byte (8)
1153
						break;
1154
				case 2:											//Buffer short (16)
1155
				case 3:	data[i] = new Integer(r.buffShort[0]);	//Buffer short (16)
1156
						break;
1157
				case 4:											//Buffer int (32)
1158
				case 5: data[i] = new Integer(r.buffInt[0]);	//Buffer int (32)
1159
						break;
1160
				case 6:	data[i] = new Float(r.buffFloat[0]);	//Buffer float (32)
1161
						break;
1162
				case 7:	data[i] = new Double(r.buffDouble[0]);	//Buffer double (64)
1163
						break;
1164
				}
1165
			}
1166
			return data;
1167
		} catch (GdalException e) {
1168
			return null;
1169
		}
1170
	}
1171
	
1172
	public int getBlockSize(){
1173
		return this.getBlockSize();
1174
	}
1175

  
1176
	/**
1177
	 * Devuelve la transformaci�n del fichero de georreferenciaci�n
1178
	 * @return AffineTransform
1179
	 */
1180
	public AffineTransform getOwnTransformation() {
1181
		return ownTransformation;
1182
	}
1183
		
1184
	/**
1185
	 * Calcula el extent en coordenadas del mundo real sin rotaci�n. Solo coordenadas y tama�o de pixel
1186
	 * @return Extent
1187
	 */
1188
	public Extent getExtentWithoutRot() {
1189
		AffineTransform at = new AffineTransform(	externalTransformation.getScaleX(), 0, 
1190
													0, externalTransformation.getScaleY(), 
1191
													externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1192
		Point2D p1 = new Point2D.Double(0, 0);
1193
		Point2D p2 = new Point2D.Double(width, height);
1194
		at.transform(p1, p1);
1195
		at.transform(p2, p2);
1196
		return new ExtentImpl(p1, p2);
1197
	}
1198
	
1199
	/**
1200
	 * Asigna una transformaci�n que es aplicada sobre la que ya tiene el propio fichero
1201
	 * @param t
1202
	 */
1203
	public void setExternalTransform(AffineTransform t){
1204
		externalTransformation = t;
1205
	}
1206

  
1207
	/**
1208
	 * Obtiene el nombre del driver de Gdal
1209
	 * @return Cadena que representa el nombre del driver de gdal
1210
	 */
1211
	public String getGdalShortName() {
1212
		return shortName;
1213
	}
1214
		
1215
}
1216

  
1217

  
1218

  
1219

  
0 1220

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/features/ILWIS_MprFeatures.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io.features;
23

  
24
import org.gvsig.raster.gdal.io.GdalProvider;
25
import org.gvsig.raster.gdal.io.GdalWriter;
26
import org.gvsig.raster.impl.store.WriteFileFormatFeatures;
27
/**
28
 * Caracteristicas del formato ILWIS para escritura.
29
 * Soporta tipos de datos enteros en 8, 16 y 32 bits y coma flotante en 32 y 64 bits
30
 * Genera un fichero .mpl con la informaci?n de contenido (ficheros), un fichero .grf con la
31
 * georreferenciaci?n, y dos ficheros por banda. Un .mpr con la informaci?n referente a los
32
 * datos de la banda y un .mp# con los datos de la banda
33
 * 
34
 * @version 04/06/2007
35
 * @author Nacho Brodin (nachobrodin@gmail.com)
36
 */
37
public class ILWIS_MprFeatures extends WriteFileFormatFeatures {
38

  
39
	public ILWIS_MprFeatures() {
40
		super(GdalProvider.FORMAT_ILWIS, "mpl", new int[] { -1 }, new int[] { 0, 1, 2, 3, 4, 5 }, GdalWriter.class);
41
	}
42

  
43
	/**
44
	 * Carga los par?metros de este driver.
45
	 */
46
	public void loadParams() {
47
		super.loadParams();
48
	}
49
}
0 50

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/features/JpegFeatures.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io.features;
23

  
24
import org.gvsig.fmap.dal.coverage.datastruct.Params;
25
import org.gvsig.raster.gdal.io.JpegWriter;
26
import org.gvsig.raster.impl.store.WriteFileFormatFeatures;
27
/**
28
 * Caracteristicas del formato Jpeg para escritura.
29
 * Soporta escritura de imagenes 1 banda (monocromo) o 3 (RGB) en 8 bits. 
30
 * La georreferenciaci?n puede hacerse mediante un fichero .wld.
31
 * 
32
 * @version 04/06/2007
33
 * @author Nacho Brodin (nachobrodin@gmail.com)
34
 *
35
 */
36
public class JpegFeatures extends WriteFileFormatFeatures {
37
	
38
	public JpegFeatures() {
39
		super("Jpeg", "jpg", new int[]{3}, null, JpegWriter.class);
40
	}
41
	
42
	/**
43
	 * Carga los par?metros de este driver.
44
	 */
45
	public void loadParams() {
46
		super.loadParams();
47
		
48
		driverParams.setParam("quality",
49
				new Integer(16),
50
				Params.SLIDER,
51
				new String[]{ "10", "100", "16", "5", "30"}); //min, max, valor defecto, intervalo peque?o, intervalo grande;
52

  
53
		driverParams.setParam("progressive", 
54
				new Boolean("false"), 
55
				Params.CHECK, 
56
				null);
57
	}
58
}
0 59

  
org.gvsig.raster.gdal/trunk/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/gdal/io/features/PNM_PpmFeatures.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io.features;
23

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff