Revision 2036

View differences:

org.gvsig.raster.gdal/tags/tagdate_29082013/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
1
org.gvsig.raster.gdal.io.DefaultGdalIOLibrary
0 2

  
org.gvsig.raster.gdal/tags/tagdate_29082013/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/memory/io/MemoryRasterProvider.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.memory.io;
23

  
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Point2D;
26
import java.awt.geom.Rectangle2D;
27

  
28
import org.cresques.cts.ICoordTrans;
29
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
30
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
31
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
32
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
33
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
34
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
35
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
36
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
37
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
38
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
39
import org.gvsig.metadata.MetadataLocator;
40
import org.gvsig.raster.cache.tile.provider.TileListener;
41
import org.gvsig.raster.cache.tile.provider.TileServer;
42
import org.gvsig.raster.impl.datastruct.ExtentImpl;
43
import org.gvsig.raster.impl.provider.DefaultRasterProvider;
44
import org.gvsig.raster.impl.provider.RasterProvider;
45
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
46
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.task.TaskStatus;
49

  
50
/**
51
 * Driver para datos cargados en un objeto IBuffer
52
 * @author Nacho Brodin (nachobrodin@gmail.com)
53
 *
54
 */
55
public class MemoryRasterProvider extends DefaultRasterProvider {
56
	public static String        NAME                     = "Gdal Store";
57
	public static String        DESCRIPTION              = "Gdal Raster file";
58
	public static final String  METADATA_DEFINITION_NAME = "GdalStore";
59
	
60
	private Extent              v                        = null;
61
	protected Buffer            buffer                   = null;
62
	private Extent 		        extent                   = null;
63
	private boolean             open                     = false;
64
	
65
	/**
66
	 * Estado de transparencia del raster.
67
	 */
68
	protected DataStoreTransparency   fileTransparency = null;
69

  
70
	public static void register() {
71
	}
72
	
73
	/*
74
	 * (non-Javadoc)
75
	 * @see org.gvsig.raster.impl.provider.RasterProvider#registerTileProviderFormats(java.lang.Class)
76
	 */
77
	public void registerTileProviderFormats(Class<RasterProvider> c) {
78
		
79
	}
80
	
81
	/**
82
	 * Mandatory constructor to instantiate an empty provider
83
	 */
84
	public MemoryRasterProvider() {}
85

  
86
	/**
87
	 * Constructor. Asigna el buffer de datos y la extensi?n
88
	 * @param proj Proyecci?n
89
	 * @param buf Buffer
90
	 * @throws NotSupportedExtensionException
91
	 */
92
	public MemoryRasterProvider(AbstractRasterDataParameters params,
93
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
94
		super(params, storeServices, ToolsLocator.getDynObjectManager()
95
				.createDynObject(
96
						MetadataLocator.getMetadataManager().getDefinition(
97
								METADATA_DEFINITION_NAME)));
98
		setParam(storeServices, params);
99
		if(!(params instanceof MemoryDataParameters))
100
			throw new NotSupportedExtensionException("Buffer not supported");
101

  
102
		extent = ((MemoryDataParameters)params).getExtent();
103
		this.buffer = ((MemoryDataParameters)params).getBuffer();
104

  
105
		if(extent != null) {
106
			double psX = (extent.maxX() - extent.minX()) / buffer.getWidth();
107
			double psY = (extent.minY() - extent.maxY()) / buffer.getHeight();
108
			ownTransformation = new AffineTransform(psX, 0, 0, psY, extent.minX(), extent.maxY());
109
		} else
110
			ownTransformation = new AffineTransform(1, 0, 0, -1, 0, buffer.getHeight());
111

  
112
		if(buffer == null)
113
			throw new NotSupportedExtensionException("Buffer invalid");
114

  
115
		load();
116
		bandCount = buffer.getBandCount();
117

  
118
		//Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
119
		int[] dt = new int[buffer.getBandCount()];
120
		for (int i = 0; i < dt.length; i++)
121
			dt[i] = buffer.getDataType();
122
		setDataType(dt);
123
		open = true;
124
	}
125

  
126
	/*
127
	 *  (non-Javadoc)
128
	 * @see org.gvsig.raster.dataset.GeoInfo#load()
129
	 */
130
	public RasterProvider load() {
131
		return this;
132
	}
133
	
134
	/*
135
	 * (non-Javadoc)
136
	 * @see org.gvsig.raster.impl.provider.RasterProvider#isOpen()
137
	 */
138
	public boolean isOpen() {
139
		return open;
140
	}
141

  
142
	/*
143
	 *  (non-Javadoc)
144
	 * @see org.gvsig.raster.dataset.GeoInfo#close()
145
	 */
146
	public void close() {
147
		buffer = null;
148
		open = false;
149
	}
150

  
151
	/**
152
	 * Asigna el extent de la vista actual.
153
	 */
154
	public void setView(Extent e) {
155
		v = e;
156
	}
157

  
158
	/**
159
	 * Obtiene extent de la vista actual
160
	 */
161
	public Extent getView() {
162
		return v;
163
	}
164

  
165
	/**
166
	 * Obtiene la anchura del fichero
167
	 */
168
	public double getWidth() {
169
		return buffer.getWidth();
170
	}
171

  
172
	/**
173
	 * Obtiene la altura del fichero
174
	 */
175
	public double getHeight() {
176
		return buffer.getHeight();
177
	}
178

  
179
	/*
180
	 *  (non-Javadoc)
181
	 * @see org.cresques.geo.Projected#reProject(org.cresques.cts.ICoordTrans)
182
	 */
183
	public void reProject(ICoordTrans rp) {
184
	}
185

  
186
	/**
187
	 * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
188
	 * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image,
189
	 * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda.
190
	 * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose
191
	 * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
192
	 * <UL>
193
	 * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
194
	 * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
195
	 * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
196
	 * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
197
	 * </UL>
198
	 *
199
	 * @return
200
	 */
201
	/*private boolean[] getOrientation(){
202
		boolean[] orientation = {true, false};
203
		return orientation;
204
	}*/
205

  
206
	/* (non-Javadoc)
207
	 * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
208
	 */
209
	public Object getData(int x, int y, int band) {
210
		if(buffer.getDataType() == Buffer.TYPE_BYTE){
211
			return new Integer(buffer.getElemByte(y, x, band));
212
		}else if(buffer.getDataType() == Buffer.TYPE_SHORT){
213
			return new Integer(buffer.getElemShort(y, x, band));
214
		}else if(buffer.getDataType() == Buffer.TYPE_INT){
215
			return new Integer(buffer.getElemInt(y, x, band));
216
		}else if(buffer.getDataType() == Buffer.TYPE_FLOAT){
217
			return new Float(buffer.getElemFloat(y, x, band));
218
		}else if(buffer.getDataType() == Buffer.TYPE_DOUBLE){
219
			return new Double(buffer.getElemDouble(y, x, band));
220
		}
221
		return null;
222
	}
223

  
224

  
225
	/**
226
	 * Devuelve el tama?o de bloque
227
	 * @return Tama?o de bloque
228
	 */
229
	public int getBlockSize(){
230
		return 0;
231
	}
232

  
233
	/**
234
	 * Obtiene el flag que dice si la imagen est? o no georreferenciada
235
	 * @return true si est? georreferenciada y false si no lo est?.
236
	 */
237
	public boolean isGeoreferenced() {
238
		return (this.extent != null);
239
	}
240

  
241
	/**
242
	 * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
243
	 * el valor de esta variable cada vez que dibuja.
244
	 * @return true si se ha supersampleado y false si no se ha hecho.
245
	 */
246
	public boolean isSupersampling() {
247
		return false;
248
	}
249

  
250
	/**
251
	 * @return Returns the dataType.
252
	 */
253
	public int[] getDataType() {
254
		int[] dt = new int[buffer.getBandCount()];
255
		for (int i = 0; i < dt.length; i++)
256
			dt[i] = buffer.getDataType();
257
		return dt;
258
	}
259

  
260
	/**
261
	 * Ajusta los puntos pasados por par?metro a los l?mites del buffer. Es decir si alguno excede
262
	 * los l?mites por arriba o por abajo los ajusta.
263
	 * @param begin Punto inicial
264
	 * @param end Punto final
265
	 */
266
	private void adjustPointsToBufferLimits(Point2D begin, Point2D end) {
267
		if(begin.getX() < 0)
268
			begin.setLocation(0, begin.getY());
269
		if(begin.getY() > buffer.getHeight())
270
			begin.setLocation(begin.getX(), buffer.getHeight());
271
		if(end.getY() < 0)
272
			end.setLocation(begin.getX(), 0);
273
		if(end.getX() > buffer.getWidth())
274
			begin.setLocation(buffer.getWidth(), begin.getY());
275
	}
276
	
277
	/*
278
	 * (non-Javadoc)
279
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(org.gvsig.fmap.dal.coverage.datastruct.Extent, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.raster.cache.tile.provider.TileListener)
280
	 */
281
	public void getWindow(Extent ex, int bufWidth, int bufHeight, 
282
			BandList bandList, TileListener listener, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
283
		 
284
	}
285

  
286
	/*
287
	 * (non-Javadoc)
288
	 * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.Buffer)
289
	 */
290
	public Buffer getWindow(Extent ex, BandList bandList, Buffer rasterBuf, TaskStatus status) {
291
		Point2D begin = worldToRaster(new Point2D.Double(ex.getULX(), ex.getULY()));
292
		Point2D end = worldToRaster(new Point2D.Double(ex.getLRX(), ex.getLRY()));
293
		setView(ex);
294

  
295
		adjustPointsToBufferLimits(begin, end);
296

  
297
		switch(buffer.getDataType()){
298
		case Buffer.TYPE_BYTE: writeByteBuffer(rasterBuf, 1, 1, begin, bandList); break;
299
		case Buffer.TYPE_SHORT: writeShortBuffer(rasterBuf, 1, 1, begin, bandList); break;
300
		case Buffer.TYPE_INT: writeIntBuffer(rasterBuf, 1, 1, begin, bandList); break;
301
		case Buffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, 1, 1, begin, bandList); break;
302
		case Buffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, 1, 1, begin, bandList); break;
303
		}
304
		return rasterBuf;
305
	}
306

  
307
	/*
308
	 *  (non-Javadoc)
309
	 * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.Buffer, boolean)
310
	 */
311
	public Buffer getWindow(double x, double y, double w, double h, 
312
			BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) {
313
		Point2D begin = worldToRaster(new Point2D.Double(x, y));
314
		Point2D end = worldToRaster(new Point2D.Double(x + w, y - h));
315
		setView(new ExtentImpl(x, y, x + w, y - h));
316

  
317
		adjustPointsToBufferLimits(begin, end);
318

  
319
		switch(buffer.getDataType()){
320
		case Buffer.TYPE_BYTE: writeByteBuffer(rasterBuf, 1, 1, begin, bandList); break;
321
		case Buffer.TYPE_SHORT: writeShortBuffer(rasterBuf, 1, 1, begin, bandList); break;
322
		case Buffer.TYPE_INT: writeIntBuffer(rasterBuf, 1, 1, begin, bandList); break;
323
		case Buffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, 1, 1, begin, bandList); break;
324
		case Buffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, 1, 1, begin, bandList); break;
325
		}
326
		return rasterBuf;
327
	}
328

  
329
	/*
330
	 *  (non-Javadoc)
331
	 * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.Buffer, boolean)
332
	 */
333
	public Buffer getWindow(Extent extent, int bufWidth, int bufHeight, 
334
			BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) {
335
		Point2D begin = worldToRaster(new Point2D.Double(extent.getMin().getX(), extent.getMax().getY()));
336
		Point2D end = worldToRaster(new Point2D.Double(extent.getMax().getX(), extent.getMin().getY()));
337
		setView(extent);
338

  
339
		adjustPointsToBufferLimits(begin, end);
340

  
341
		//Ancho y alto en pixels (double) del area seleccionada.
342
		double w = Math.abs(end.getX() - begin.getX());
343
		double h = Math.abs(end.getY() - begin.getY());
344

  
345
		//Relaci?n entre el n?mero de pixels del buffer origen (area seleccionada) y el destino
346
		double stepX = w / ((double)bufWidth);
347
		double stepY = h / ((double)bufHeight);
348

  
349
		//Escritura separada en 5 llamadas para mejorar el rendimiento
350
		switch(buffer.getDataType()){
351
		case Buffer.TYPE_BYTE: writeByteBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
352
		case Buffer.TYPE_SHORT: writeShortBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
353
		case Buffer.TYPE_INT: writeIntBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
354
		case Buffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
355
		case Buffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
356
		}
357

  
358
		/*int xPx = 0, yPx = 0;
359
		for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++) {
360
			yPx = 0;
361
			for(double row = begin.getY(); yPx < bufHeight; row += stepY) {
362
				xPx = 0;
363
				for(double col = begin.getX(); xPx < bufWidth; col += stepX) {
364
					switch(buffer.getDataType()){
365
					case Buffer.TYPE_BYTE: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemByte((int)row, (int)col, iBand)); break;
366
					case Buffer.TYPE_SHORT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemShort((int)row, (int)col, iBand)); break;
367
					case Buffer.TYPE_INT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemInt((int)row, (int)col, iBand)); break;
368
					case Buffer.TYPE_FLOAT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemFloat((int)row, (int)col, iBand)); break;
369
					case Buffer.TYPE_DOUBLE: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemDouble((int)row, (int)col, iBand)); break;
370
					}
371
					xPx ++;
372
				}
373
				yPx ++;
374
			}
375
		}*/
376
		return rasterBuf;
377
	}
378

  
379
	/**
380
	 * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
381
	 * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a
382
	 * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
383
	 * @param rasterBuf Buffer donde se escriben los datos
384
	 * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
385
	 * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
386
	 * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
387
	 * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
388
	 * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
389
	 * del pixel. Esto es util cuando se supersamplea.
390
	 */
391
	private void writeByteBuffer(Buffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
392
		int xPx = 0, yPx = 0;
393
		for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
394
			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
395
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
396
				continue;
397
			for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
398
				yPx = 0;
399
				for(double row = begin.getY(); (yPx < rasterBuf.getHeight() && row < buffer.getHeight()); row += stepY) {
400
					xPx = 0;
401
					for(double col = begin.getX(); (xPx < rasterBuf.getWidth() && col < buffer.getWidth()); col += stepX) {
402
						rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemByte((int)row, (int)col, iBand));
403
						xPx ++;
404
					}
405
					yPx ++;
406
				}
407
			}
408
		}
409
	}
410

  
411
	/**
412
	 * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
413
	 * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a
414
	 * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
415
	 * @param rasterBuf Buffer donde se escriben los datos
416
	 * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
417
	 * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
418
	 * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
419
	 * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
420
	 * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
421
	 * del pixel. Esto es util cuando se supersamplea.
422
	 */
423
	private void writeShortBuffer(Buffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
424
		int xPx = 0, yPx = 0;
425
		for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
426
			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
427
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
428
				continue;
429
			for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
430
				yPx = 0;
431
				for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
432
					xPx = 0;
433
					for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
434
						rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemShort((int)row, (int)col, iBand));
435
						xPx ++;
436
					}
437
					yPx ++;
438
				}
439
			}
440
		}
441
	}
442

  
443
	/**
444
	 * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
445
	 * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a
446
	 * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
447
	 * @param rasterBuf Buffer donde se escriben los datos
448
	 * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
449
	 * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
450
	 * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
451
	 * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
452
	 * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
453
	 * del pixel. Esto es util cuando se supersamplea.
454
	 */
455
	private void writeIntBuffer(Buffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
456
		int xPx = 0, yPx = 0;
457
		for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
458
			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
459
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
460
				continue;
461
			for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
462
				yPx = 0;
463
				for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
464
					xPx = 0;
465
					for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
466
						rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemInt((int)row, (int)col, iBand));
467
						xPx ++;
468
					}
469
					yPx ++;
470
				}
471
			}
472
		}
473
	}
474

  
475
	/**
476
	 * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
477
	 * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a
478
	 * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
479
	 * @param rasterBuf Buffer donde se escriben los datos
480
	 * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
481
	 * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
482
	 * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
483
	 * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
484
	 * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
485
	 * del pixel. Esto es util cuando se supersamplea.
486
	 */
487
	private void writeFloatBuffer(Buffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
488
		int xPx = 0, yPx = 0;
489
		for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
490
			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
491
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
492
				continue;
493
			for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
494
				yPx = 0;
495
				for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
496
					xPx = 0;
497
					for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
498
						rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemFloat((int)row, (int)col, iBand));
499
						xPx ++;
500
					}
501
					yPx ++;
502
				}
503
			}
504
		}
505
	}
506

  
507
	/**
508
	 * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
509
	 * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a
510
	 * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
511
	 * @param rasterBuf Buffer donde se escriben los datos
512
	 * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
513
	 * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
514
	 * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
515
	 * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
516
	 * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
517
	 * del pixel. Esto es util cuando se supersamplea.
518
	 */
519
	private void writeDoubleBuffer(Buffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
520
		int xPx = 0, yPx = 0;
521
		for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
522
			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
523
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
524
				continue;
525
			for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
526
				yPx = 0;
527
				for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
528
					xPx = 0;
529
					for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
530
						rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemDouble((int)row, (int)col, iBand));
531
						xPx ++;
532
					}
533
					yPx ++;
534
				}
535
			}
536
		}
537
	}
538

  
539
	/*
540
	 *  (non-Javadoc)
541
	 * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.Buffer)
542
	 */
543
//	public Buffer getWindow(int x, int y, BandList bandList, Buffer rasterBuf) {
544
//		int w = rasterBuf.getWidth();
545
//		int h = rasterBuf.getHeight();
546
//		setView(
547
//				new ExtentImpl( rasterUtil.getMapRectFromPxRect(getExtent().toRectangle2D(),
548
//							getWidth(),
549
//							getHeight(),
550
//							new Rectangle2D.Double(x, y, w, h)))
551
//				);
552
//
553
//		for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++){
554
//			int[] drawableBands = bandList.getBufferBandToDraw(this.getURIOfFirstProvider(), iBand);
555
//			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
556
//				continue;
557
//			if(buffer.getDataType() == Buffer.TYPE_BYTE) {
558
//				for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
559
//					for(int line = y; line < (y + h); line ++)
560
//						for(int col = x; col < (x + w); col ++)
561
//							rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemByte(line, col, drawableBands[drawBands]));
562
//				}
563
//			}else if(buffer.getDataType() == Buffer.TYPE_SHORT){
564
//				for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
565
//					for(int line = y; line < (y + h); line ++)
566
//						for(int col = x; col < (x + w); col ++)
567
//							rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemShort(line, col, drawableBands[drawBands]));
568
//				}
569
//			}else if(buffer.getDataType() == Buffer.TYPE_INT){
570
//				for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
571
//					for(int line = y; line < (y + h); line ++)
572
//						for(int col = x; col < (x + w); col ++)
573
//							rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemInt(line, col, drawableBands[drawBands]));
574
//				}
575
//			}else if(buffer.getDataType() == Buffer.TYPE_FLOAT){
576
//				for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
577
//					for(int line = y; line < (y + h); line ++)
578
//						for(int col = x; col < (x + w); col ++)
579
//							rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemFloat(line, col, drawableBands[drawBands]));
580
//				}
581
//			}else if(buffer.getDataType() == Buffer.TYPE_DOUBLE){
582
//				for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
583
//					for(int line = y; line < (y + h); line ++)
584
//						for(int col = x; col < (x + w); col ++)
585
//							rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemDouble(line, col, drawableBands[drawBands]));
586
//				}
587
//			}
588
//		}
589
//		return rasterBuf;
590
//	}
591

  
592
	/*
593
	 *  (non-Javadoc)
594
	 * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.Buffer)
595
	 */
596
	public Buffer getWindow(int x, int y, int w, int h, 
597
			BandList bandList, Buffer rasterBuf, TaskStatus status) {
598
		setView(
599
				new ExtentImpl( rasterUtil.getMapRectFromPxRect(getExtent().toRectangle2D(),
600
							getWidth(),
601
							getHeight(),
602
							new Rectangle2D.Double(x, y, w, h)))
603
				);
604

  
605
		//Relaci?n entre el n?mero de pixels del buffer origen (area seleccionada) y el destino
606
		double stepX = w / ((double)rasterBuf.getWidth());
607
		double stepY = h / ((double)rasterBuf.getHeight());
608
		switch(buffer.getDataType()){
609
		case Buffer.TYPE_BYTE: writeByteBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
610
		case Buffer.TYPE_SHORT: writeShortBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
611
		case Buffer.TYPE_INT: writeIntBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
612
		case Buffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
613
		case Buffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
614
		}
615
		return rasterBuf;
616
	}
617

  
618
	/*
619
	 *  (non-Javadoc)
620
	 * @see org.gvsig.raster.dataset.RasterDataset#readCompleteLine(int, int)
621
	 */
622
	public Object readCompleteLine(int line, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
623
		switch(buffer.getDataType()){
624
		case Buffer.TYPE_BYTE: return buffer.getLineFromBandByte(line, band);
625
		case Buffer.TYPE_SHORT: return buffer.getLineFromBandShort(line, band);
626
		case Buffer.TYPE_INT: return buffer.getLineFromBandInt(line, band);
627
		case Buffer.TYPE_FLOAT: return buffer.getLineFromBandFloat(line, band);
628
		case Buffer.TYPE_DOUBLE: return buffer.getLineFromBandDouble(line, band);
629
		}
630
		return null;
631
	}
632

  
633
	/*
634
	 *  (non-Javadoc)
635
	 * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int, double)
636
	 */
637
	public Object readBlock(int pos, int blockHeight, double scale) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
638
		if(pos < 0)
639
			throw new InvalidSetViewException("Request out of grid");
640

  
641
		if((pos + blockHeight) > buffer.getHeight())
642
			blockHeight = Math.abs(buffer.getHeight() - pos);
643

  
644
		switch(buffer.getDataType()){
645
		case Buffer.TYPE_BYTE:
646
			byte[][][] bufb = new byte[getBandCount()][][];
647
			for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
648
				for (int row = 0; row < blockHeight; row++) {
649
					bufb[iBand][row] = buffer.getLineFromBandByte(row, iBand);
650
				}
651
			}
652
			return bufb;
653
		case Buffer.TYPE_SHORT:
654
			short[][][] bufs = new short[getBandCount()][][];
655
			for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
656
				for (int row = 0; row < blockHeight; row++) {
657
					bufs[iBand][row] = buffer.getLineFromBandShort(row, iBand);
658
				}
659
			}
660
			return bufs;
661
		case Buffer.TYPE_INT:
662
			int[][][] bufi = new int[getBandCount()][][];
663
			for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
664
				for (int row = 0; row < blockHeight; row++) {
665
					bufi[iBand][row] = buffer.getLineFromBandInt(row, iBand);
666
				}
667
			}
668
			return bufi;
669
		case Buffer.TYPE_FLOAT:
670
			float[][][] buff = new float[getBandCount()][][];
671
			for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
672
				for (int row = 0; row < blockHeight; row++) {
673
					buff[iBand][row] = buffer.getLineFromBandFloat(row, iBand);
674
				}
675
			}
676
			return buff;
677
		case Buffer.TYPE_DOUBLE:
678
			double[][][] bufd = new double[getBandCount()][][];
679
			for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
680
				for (int row = 0; row < blockHeight; row++) {
681
					bufd[iBand][row] = buffer.getLineFromBandDouble(row, iBand);
682
				}
683
			}
684
			return bufd;
685
		}
686
		return null;
687
	}
688

  
689
		/**
690
	 * Obtiene el objeto que contiene el estado de la transparencia
691
	 */
692
	public DataStoreTransparency getTransparency() {
693
		if(fileTransparency == null)
694
			fileTransparency = new DataStoreTransparency();
695
		return fileTransparency;
696
	}
697

  
698
	/*
699
	 * (non-Javadoc)
700
	 * @see org.gvsig.raster.dataset.RasterDataset#getOverviewCount(int)
701
	 */
702
	public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
703
		if(band >= getBandCount())
704
			throw new BandAccessException("Wrong band");
705
		return 0;
706
	}
707

  
708
	/*
709
	 * (non-Javadoc)
710
	 * @see org.gvsig.raster.dataset.RasterDataset#getOverviewWidth(int, int)
711
	 */
712
	public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
713
		if (band >= getBandCount())
714
			throw new BandAccessException("Wrong band");
715
		return 0;
716
	}
717

  
718
	/*
719
	 * (non-Javadoc)
720
	 * @see org.gvsig.raster.dataset.RasterDataset#getOverviewWidth(int, int)
721
	 */
722
	public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
723
		if (band >= getBandCount())
724
			throw new BandAccessException("Wrong band");
725
		return 0;
726
	}
727

  
728
	/*
729
	 * (non-Javadoc)
730
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#isOverviewsSupported()
731
	 */
732
	public boolean isOverviewsSupported() {
733
		return false;
734
	}
735
	
736
	/*
737
	 * (non-Javadoc)
738
	 * @see org.gvsig.fmap.dal.raster.spi.CoverageStoreProvider#getName()
739
	 */
740
	public String getName() {
741
		return NAME;
742
	}
743
	
744
	/*
745
	 * (non-Javadoc)
746
	 * @see org.gvsig.raster.impl.provider.RasterProvider#setStatus(org.gvsig.raster.impl.provider.RasterProvider)
747
	 */
748
	public void setStatus(RasterProvider provider) {
749
		if(provider instanceof MemoryRasterProvider) {
750
			//Not implemented yet
751
		}
752
	}
753
	
754
	/*
755
	 * (non-Javadoc)
756
	 * @see org.gvsig.raster.impl.provider.RasterProvider#getTileServer()
757
	 */
758
	public TileServer getTileServer() {
759
		return null;
760
	}
761
}
0 762

  
org.gvsig.raster.gdal/tags/tagdate_29082013/org.gvsig.raster.gdal/org.gvsig.raster.gdal.io/src/main/java/org/gvsig/raster/memory/io/MemoryDataParameters.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

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

  
28
package org.gvsig.raster.memory.io;
29

  
30
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
31
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
32
import org.gvsig.raster.impl.store.AbstractRasterFileDataParameters;
33

  
34
/**
35
 * Parameters for the memory provider
36
 * @author Nacho Brodin (nachobrodin@gmail.com)
37
 */
38
public class MemoryDataParameters extends AbstractRasterFileDataParameters {
39
	private final String id = "memory";
40
	private Buffer buffer = null;
41
	private Extent extent = null;
42
	
43
	/**
44
	 * Constructor vacio
45
	 */
46
	public MemoryDataParameters() {
47
	}
48
	
49
	/**
50
	 * Contructor
51
	 * @param buf buffer del driver
52
	 * @param ext extensi?n del buffer
53
	 */
54
	public MemoryDataParameters(Buffer buf, Extent ext) {
55
		this.buffer = buf;
56
		this.extent = ext;
57
	}
58
	
59
	/**
60
	 * Obtiene el buffer de datos
61
	 * @return Buffer
62
	 */
63
	public Buffer getBuffer() {
64
		return buffer;
65
	}
66
	
67
	/**
68
	 * Asigna el buffer de datos
69
	 * @param buffer Buffer
70
	 */
71
	public void setBuffer(Buffer buffer) {
72
		this.buffer = buffer;
73
	}
74
	
75
	/**
76
	 * Obtiene la extensi?n del buffer de datos
77
	 * @return Extent
78
	 */
79
	public Extent getExtent() {
80
		return extent;
81
	}
82
	
83
	/**O
84
	 * Asigna la extensi?n del buffer de datos
85
	 * @param extent
86
	 */
87
	public void setExtent(Extent extent) {
88
		this.extent = extent;
89
	}
90

  
91
	/**
92
	 * Obtiene el identificador del driver
93
	 * @return String 
94
	 */
95
	public String getFormatID() {
96
		return id;
97
	}
98
	
99
	/*
100
	 * (non-Javadoc)
101
	 * @see org.gvsig.fmap.dal.DataStoreParameters#getDataStoreName()
102
	 */
103
	public String getDataStoreName() {
104
		return MemoryRasterProvider.NAME;
105
	}
106
	
107
	/*
108
	 * (non-Javadoc)
109
	 * @see org.gvsig.fmap.dal.DataStoreParameters#getDescription()
110
	 */
111
	public String getDescription() {
112
		return MemoryRasterProvider.DESCRIPTION;
113
	}
114
}
0 115

  
org.gvsig.raster.gdal/tags/tagdate_29082013/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.Color;
25
import java.awt.geom.AffineTransform;
26
import java.awt.geom.NoninvertibleTransformException;
27
import java.awt.geom.Point2D;
28
import java.io.IOException;
29
import java.util.ArrayList;
30
import java.util.List;
31

  
32
import org.gvsig.fmap.dal.coverage.RasterLibrary;
33
import org.gvsig.fmap.dal.coverage.RasterLocator;
34
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
35
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
36
import org.gvsig.fmap.dal.coverage.datastruct.ColorItem;
37
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
38
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
39
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
40
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
41
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
42
import org.gvsig.fmap.dal.coverage.util.FileUtils;
43
import org.gvsig.jgdal.Gdal;
44
import org.gvsig.jgdal.GdalBuffer;
45
import org.gvsig.jgdal.GdalColorEntry;
46
import org.gvsig.jgdal.GdalColorTable;
47
import org.gvsig.jgdal.GdalException;
48
import org.gvsig.jgdal.GdalRasterBand;
49
import org.gvsig.jgdal.GeoTransform;
50
import org.gvsig.raster.impl.datastruct.ColorItemImpl;
51
import org.gvsig.raster.impl.datastruct.DefaultNoData;
52
import org.gvsig.raster.impl.datastruct.ExtentImpl;
53
import org.gvsig.raster.impl.process.RasterTask;
54
import org.gvsig.raster.impl.process.RasterTaskQueue;
55
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
56
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
57
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
58
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
59
import org.gvsig.tools.dispose.Disposable;
60
import org.gvsig.tools.task.TaskStatus;
61
/**
62
 * Soporte 'nativo' para ficheros desde GDAL.
63
 * 
64
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
65
 * @author Nacho Brodin (nachobrodin@gmail.com)
66
 */
67
public class GdalNative extends Gdal implements Disposable {
68
	private String                       fileName                = null;
69
	private String                       shortName               = "";
70
	public 	GeoTransform                 trans                   = null;
71
	public int                           width                   = 0, height = 0;
72
	public double                        originX                 = 0D, originY = 0D;
73
	public String                        version                 = "";
74
	protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
75
	private int[]                        dataType                = null;
76
	DataStoreMetadata                    metadata                = null;
77
	protected boolean                    georeferenced           = true;
78
	
79
	/**
80
	 * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
81
	 * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
82
	 * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
83
	 * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
84
	 * distinto tama?o que el resto.   
85
	 */
86
	public int[]                              stepArrayX             = null;
87
	public int[]                              stepArrayY             = null;
88
	protected GdalRasterBand[]                gdalBands              = null;
89
	private double                            lastReadLine           = -1;
90
	private int                               currentFullWidth       = -1;
91
	private int                               currentFullHeight      = -1;
92
	private int                               currentViewWidth       = -1;
93
	private int                               currentViewHeight      = -1;
94
	private double                            currentViewX           = 0D;
95
	private double                            viewportScaleX         = 0D;
96
	private double                            viewportScaleY         = 0D;
97
	private double                            stepX                  = 0D;
98
	private double                            stepY                  = 0D;
99
	public boolean                            isSupersampling        = false;
100
	private boolean                           open                   = false;
101
	/**
102
	 * Estado de transparencia del raster.
103
	 */
104
	protected DataStoreTransparency           fileTransparency       = null;
105
	protected DataStoreColorTable             palette                = null;
106
	protected DataStoreColorInterpretation    colorInterpr           = null;
107
	protected AffineTransform                 ownTransformation      = null;
108
	protected AffineTransform                 externalTransformation = new AffineTransform();
109
	
110
	public static int getGdalTypeFromRasterBufType(int rasterBufType) {
111
		switch (rasterBufType) {
112
			case Buffer.TYPE_BYTE: return Gdal.GDT_Byte;
113
			case Buffer.TYPE_USHORT: return Gdal.GDT_UInt16;
114
			case Buffer.TYPE_SHORT: return Gdal.GDT_Int16;
115
			case Buffer.TYPE_INT: return Gdal.GDT_Int32;
116
			case Buffer.TYPE_FLOAT: return Gdal.GDT_Float32;
117
			case Buffer.TYPE_DOUBLE: return Gdal.GDT_Float64;
118
			case Buffer.TYPE_UNDEFINED: return Gdal.GDT_Unknown;
119
			case Buffer.TYPE_IMAGE: return Gdal.GDT_Byte;
120
		}
121
		return Gdal.GDT_Unknown;
122
	}
123
	
124
	/**
125
	 * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
126
	 * @param gdalType Tipo de dato de gdal
127
	 * @return Tipo de dato de RasterBuf
128
	 */
129
	public static int getRasterBufTypeFromGdalType(int gdalType) {
130
		switch (gdalType) {
131
			case 1:// Eight bit unsigned integer GDT_Byte = 1
132
				return Buffer.TYPE_BYTE;
133

  
134
			case 3:// Sixteen bit signed integer GDT_Int16 = 3,
135
				return Buffer.TYPE_SHORT;
136

  
137
			case 2:// Sixteen bit unsigned integer GDT_UInt16 = 2
138
				//return RasterBuffer.TYPE_USHORT;
139
				return Buffer.TYPE_SHORT; //Apa?o para usar los tipos de datos que soportamos
140

  
141
			case 5:// Thirty two bit signed integer GDT_Int32 = 5
142
				return Buffer.TYPE_INT;
143

  
144
			case 6:// Thirty two bit floating point GDT_Float32 = 6
145
				return Buffer.TYPE_FLOAT;
146

  
147
			case 7:// Sixty four bit floating point GDT_Float64 = 7
148
				return Buffer.TYPE_DOUBLE;
149

  
150
				// TODO:Estos tipos de datos no podemos gestionarlos. Habria que definir
151
				// el tipo complejo y usar el tipo long que de momento no se gasta.
152
			case 4:// Thirty two bit unsigned integer GDT_UInt32 = 4,
153
				return Buffer.TYPE_INT;
154
				//return RasterBuffer.TYPE_UNDEFINED; // Deberia devolver un Long
155

  
156
			case 8:// Complex Int16 GDT_CInt16 = 8
157
			case 9:// Complex Int32 GDT_CInt32 = 9
158
			case 10:// Complex Float32 GDT_CFloat32 = 10
159
			case 11:// Complex Float64 GDT_CFloat64 = 11
160
				return Buffer.TYPE_UNDEFINED;
161
		}
162
		return Buffer.TYPE_UNDEFINED;
163
	}
164
	
165
	/**
166
	 * Overview usada en el ?ltimo setView
167
	 */
168
	int currentOverview = -1;
169
	
170
	public GdalNative(String fName) throws GdalException, IOException {
171
		super();
172
		init(fName);
173
	}
174
	
175
	private void init(String fName) throws GdalException, IOException {
176
		fileName = fName;
177
		open(fName, GA_ReadOnly);
178
		open = true;
179
		if (getPtro() == -1)
180
			throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
181
//		ext = RasterUtilities.getExtensionFromFileName(fName);
182
		width = getRasterXSize();
183
		height = getRasterYSize();
184

  
185
		int[] dt = new int[getRasterCount()];
186
		for (int i = 0; i < getRasterCount(); i++)
187
			dt[i] = this.getRasterBand(i + 1).getRasterDataType();
188
		setDataType(dt);
189
		shortName = getDriverShortName();
190
		fileTransparency = new DataStoreTransparency();
191
		colorInterpr = new DataStoreColorInterpretation();
192
		metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
193

  
194
		// Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
195
		// nos sirve para saber que banda de la imagen va asignada a cada banda de
196
		// visualizaci?n (ARGB)
197
		colorInterpr.initColorInterpretation(getRasterCount());
198
		metadata.initNoDataByBand(getRasterCount());
199
		for (int i = 0; i < getRasterCount(); i++) {
200
			GdalRasterBand rb = getRasterBand(i + 1);
201
			String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
202
			metadata.setNoDataEnabled(rb.existsNoDataValue());
203
			if(rb.existsNoDataValue()) {
204
				metadata.setNoDataValue(i, rb.getRasterNoDataValue());
205
				metadata.setNoDataEnabled(rb.existsNoDataValue());
206
			}
207
			colorInterpr.setColorInterpValue(i, colorInt);
208
			if (colorInt.equals("Alpha"))
209
				fileTransparency.setTransparencyBand(i);
210

  
211
			if (rb.getRasterColorTable() != null && palette == null) {
212
				palette = new DataStoreColorTable(gdalColorTable2ColorItems(rb.getRasterColorTable()), false);
213
//				fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
214
			}
215
		}
216
		fileTransparency.setTransparencyByPixelFromMetadata(metadata);
217

  
218
		try {
219
			trans = getGeoTransform();
220

  
221
			boolean isCorrect = false;
222
			for (int i = 0; i < trans.adfgeotransform.length; i++)
223
				if (trans.adfgeotransform[i] != 0)
224
					isCorrect = true;
225
			if (!isCorrect)
226
				throw new GdalException("");
227

  
228
			ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
229
			externalTransformation = (AffineTransform) ownTransformation.clone();
230
			currentFullWidth = width;
231
			currentFullHeight = height;
232

  
233
			this.georeferenced = true;
234
		} catch (GdalException exc) {
235
			// Transformaci�n para ficheros sin georreferenciaci�n. Se invierte la Y
236
			// ya que las WC decrecen de
237
			// arriba a abajo y los pixeles crecen de arriba a abajo
238
			ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
239
			externalTransformation = (AffineTransform) ownTransformation.clone();
240
			currentFullWidth = width;
241
			currentFullHeight = height;
242
			this.georeferenced = false;
243
		}
244
	}
245
	
246
	/**
247
	 * Returns true if this provider is open and false if don't
248
	 * @return
249
	 */
250
	public boolean isOpen() {
251
		return open;
252
	}
253
	
254
	/**
255
	 * Obtiene el flag que informa de si el raster tiene valor no data o no.
256
	 * Consultar� todas las bandas del mismo y si alguna tiene valor no data
257
	 * devuelve true sino devolver� false.
258
	 * @return true si tiene valor no data y false si no lo tiene
259
	 * @throws GdalException
260
	 */
261
	public boolean existsNoDataValue() throws GdalException {
262
		for (int i = 0; i < getRasterCount(); i++) {
263
			GdalRasterBand rb = getRasterBand(i + 1);
264
			if (rb.existsNoDataValue())
265
				return true;
266
		}
267
		return false;
268
	}
269
	
270
	/**
271
	 * Obtiene el flag que informa de si el raster tiene valor no data o no
272
	 * en una banda concreta.
273
	 * @return true si tiene valor no data en esa banda y false si no lo tiene
274
	 * @param band Posici�n de la banda a consultar (0..n)
275
	 * @throws GdalException
276
	 */
277
	public boolean existsNoDataValue(int band) throws GdalException {
278
		GdalRasterBand rb = getRasterBand(band + 1);
279
		return rb.existsNoDataValue();
280
	}
281

  
282
	/**
283
	 * Gets nodata value
284
	 * @return
285
	 */
286
	public NoData getNoDataValue() {
287
		Number value = null;
288
		int type = getRasterBufTypeFromGdalType(getDataType()[0]);
289
		if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
290
			switch (type) {
291
			case Buffer.TYPE_BYTE:
292
				if (metadata == null || metadata.getNoDataValue().length == 0)
293
					value = new Byte(RasterLibrary.defaultByteNoDataValue);
294
				else
295
					value = new Byte((byte)metadata.getNoDataValue()[0]);
296
				break;
297
			case Buffer.TYPE_SHORT:
298
				if (metadata == null || metadata.getNoDataValue().length == 0)
299
					value = new Short(RasterLibrary.defaultShortNoDataValue);
300
				else
301
					value = new Short((short)metadata.getNoDataValue()[0]);
302
				break;
303
			case Buffer.TYPE_INT:
304
				if (metadata == null || metadata.getNoDataValue().length == 0)
305
					value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
306
				else
307
					value = new Integer((int)metadata.getNoDataValue()[0]);
308
				break;
309
			case Buffer.TYPE_FLOAT:
310
				if (metadata == null || metadata.getNoDataValue().length == 0)
311
					value = new Float(RasterLibrary.defaultFloatNoDataValue);
312
				else
313
					value = new Float(metadata.getNoDataValue()[0]);
314
				break;
315
			case Buffer.TYPE_DOUBLE:
316
				if (metadata == null || metadata.getNoDataValue().length == 0)
317
					value = new Double(RasterLibrary.defaultFloatNoDataValue);
318
				else
319
					value = new Double(metadata.getNoDataValue()[0]);
320
				break;
321
			}
322
		}
323

  
324
		return new DefaultNoData(value, value, fileName);
325
	}
326

  
327
	/**
328
	 * Asigna el tipo de dato
329
	 * @param dt entero que representa el tipo de dato
330
	 */
331
	public void setDataType(int[] dt) { 
332
		dataType = dt; 
333
	}
334
	
335
	/**
336
	 * Obtiene el tipo de dato
337
	 * @return entero que representa el tipo de dato
338
	 */
339
	public int[] getDataType() { 
340
		return dataType; 
341
	}
342
	
343
	/**
344
	 * Gets the color interpretation
345
	 * @return
346
	 */
347
	public ColorInterpretation getColorInterpretation() { 
348
		return colorInterpr; 
349
	}
350
	
351
	/**
352
	 * Gets the color table
353
	 * @return
354
	 */
355
	public ColorTable getColorTable() {
356
		return palette;
357
	}
358
	
359
	/**
360
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
361
	 * del punto real.
362
	 * Supone rasters no girados
363
	 * @param pt	punto en coordenadas del punto real
364
	 * @return	punto en coordenadas del raster
365
	 */
366
	public Point2D worldToRasterWithoutRot(Point2D pt) {
367
		Point2D p = new Point2D.Double();
368
		AffineTransform at = new AffineTransform(	externalTransformation.getScaleX(), 0, 
369
													0, externalTransformation.getScaleY(), 
370
													externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
371
		try {
372
			at.inverseTransform(pt, p);
373
		} catch (NoninvertibleTransformException e) {
374
			return pt;
375
		}
376
		return p;
377
	}
378
		
379
	/**
380
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
381
	 * del punto real.
382
	 * Supone rasters no girados
383
	 * @param pt	punto en coordenadas del punto real
384
	 * @return	punto en coordenadas del raster
385
	 */
386
	public Point2D worldToRaster(Point2D pt) {
387
		Point2D p = new Point2D.Double();
388
		try {
389
			externalTransformation.inverseTransform(pt, p);
390
		} catch (NoninvertibleTransformException e) {
391
			return pt;
392
		}
393
		return p;
394
	}
395
	
396
	/**
397
	 * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
398
	 * reales. 
399
	 * @param pt Punto en coordenadas reales
400
	 * @return Punto en coordenadas pixel.
401
	 */
402
	public Point2D rasterToWorld(Point2D pt) {
403
		Point2D p = new Point2D.Double();
404
		externalTransformation.transform(pt, p);
405
		return p;
406
	}
407
	
408
	/**
409
	 * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
410
	 * viewPortScale, currentFullWidth y currentFulHeight
411
	 * @param coordenada pixel expresada en double que indica la posici�n superior izquierda
412
	 * @throws GdalException
413
	 */
414
	private void calcOverview(Point2D tl, Point2D br) throws GdalException {
415
		gdalBands[0] = getRasterBand(1);
416
		currentOverview = -1;
417
		if (gdalBands[0].getOverviewCount() > 0) {
418
			GdalRasterBand ovb = null;
419
			for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
420
				ovb = gdalBands[0].getOverview(i);
421
				if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
422
					currentOverview = i;
423
					viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
424
					viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
425
					stepX = 1D / viewportScaleX;
426
					stepY = 1D / viewportScaleY;
427
					currentFullWidth = ovb.getRasterBandXSize();
428
					currentFullHeight = ovb.getRasterBandYSize();
429
					currentViewX = Math.min(tl.getX(), br.getX());
430
					lastReadLine = Math.min(tl.getY(), br.getY());
431
					break;
432
				}
433
			}
434
		}
435
	}
436
	
437
	public void setView(double dWorldTLX, double dWorldTLY,
438
						double dWorldBRX, double dWorldBRY,
439
						int nWidth, int nHeight) throws GdalException {
440
		currentFullWidth = width;
441
		currentFullHeight = height;
442
		Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
443
		Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
444
		// Calcula cual es la primera l�nea a leer;
445
		currentViewWidth = nWidth;
446
		currentViewHeight = nHeight;
447
//		wcWidth = Math.abs(br.getX() - tl.getX());
448

  
449
		currentViewX = Math.min(tl.getX(), br.getX());
450

  
451
		viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
452
		viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
453
		stepX = 1D / viewportScaleX;
454
		stepY = 1D / viewportScaleY;
455

  
456
		lastReadLine = Math.min(tl.getY(), br.getY());
457
		
458
		//Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
459

  
460
		// calcula el overview a usar
461
		gdalBands = new GdalRasterBand[4];
462
		calcOverview(tl, br);
463

  
464
		// Selecciona las bandas y los overviews necesarios
465
		/*gdalBands[0] = getRasterBand(rBandNr);
466
		gdalBands[1] = gdalBands[0]; 
467
		gdalBands[2] = gdalBands[1]; 
468

  
469
		if(getRasterCount() >= 2) {
470
			gdalBands[1] = getRasterBand(gBandNr);
471
			gdalBands[2] = gdalBands[1]; 
472
		}
473
		if(this.getRasterCount() >= 3) 
474
			gdalBands[2] = getRasterBand(bBandNr);
475
		if(colorInterpr.isAlphaBand())
476
			gdalBands[3] = getRasterBand(aBandNr);			
477

  
478
		assignDataTypeFromGdalRasterBands(gdalBands);
479

  
480
		if (currentOverview > 0) {
481
			gdalBands[0] = gdalBands[0].getOverview(currentOverview);
482
			if(getRasterCount() >= 2) {
483
				gdalBands[1] = gdalBands[1].getOverview(currentOverview);
484
			}
485
			if(this.getRasterCount() >= 3) 
486
				gdalBands[2] = gdalBands[2].getOverview(currentOverview);
487
			if(colorInterpr.isAlphaBand())
488
				gdalBands[3] = gdalBands[3].getOverview(currentOverview);			
489

  
490
		}*/
491
	}
492
	
493
	/**
494
	 * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n�mero de bandas solicitado.
495
	 * @param nbands N�mero de bandas solicitado.
496
	 * @throws GdalException
497
	 */
498
	public void selectGdalBands(int nbands) throws GdalException {
499
		gdalBands = new GdalRasterBand[nbands];
500
		// Selecciona las bandas y los overviews necesarios
501
		gdalBands[0] = getRasterBand(1);
502
		for (int i = 0; i < nbands; i++)
503
			gdalBands[i] = gdalBands[0];
504

  
505
		assignDataTypeFromGdalRasterBands(gdalBands);
506
//		setDataType(gdalBands[0].getRasterDataType());
507

  
508
		for (int i = 2; i <= nbands; i++) {
509
			if (getRasterCount() >= i) {
510
				gdalBands[i - 1] = getRasterBand(i);
511
				for (int j = i; j < nbands; j++)
512
					gdalBands[j] = gdalBands[i - 1];
513
			}
514
		}
515

  
516
		if (currentOverview > 0) {
517
			gdalBands[0] = gdalBands[0].getOverview(currentOverview);
518
			for (int i = 2; i <= nbands; i++) {
519
				if (getRasterCount() >= i)
520
					gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
521
			}
522
		}
523
	}
524
		
525
	int lastY = -1;
526
	
527
	/**
528
	 * Lee una l�nea de bytes
529
	 * @param line Buffer donde se cargan los datos
530
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
531
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
532
	 * por la izquierda a mitad de pixel
533
	 * @param gdalBuffer Buffer con la l�nea de datos original
534
	 */
535
	private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
536
		double j = 0D;
537
		int i = 0;
538
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
539
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
540
				line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
541
			}
542
		}
543
	}
544
	
545
	/**
546
	 * Lee una l�nea de shorts
547
	 * @param line Buffer donde se cargan los datos
548
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
549
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
550
	 * por la izquierda a mitad de pixel
551
	 * @param gdalBuffer Buffer con la l�nea de datos original
552
	 */
553
	private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
554
		double j = 0D;
555
		int i = 0;
556
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
557
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
558
				line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
559
			}
560
		}
561
	}
562

  
563
	/**
564
	 * Lee una l�nea de ints
565
	 * @param line Buffer donde se cargan los datos
566
	 * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
567
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
568
	 * por la izquierda a mitad de pixel
569
	 * @param gdalBuffer Buffer con la l�nea de datos original
570
	 */
571
	private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
572
		double j = 0D;
573
		int i = 0;
574
		for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
575
			for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
576
				line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
577
			}
578
		}
579
	}
580

  
581
	/**
582
	 * Lee una l�nea de float
583
	 * @param line Buffer donde se cargan los datos
584
	 * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
585
	 * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff