Revision 2438 org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/buffer/DefaultRasterQuery.java

View differences:

DefaultRasterQuery.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 1
package org.gvsig.raster.impl.buffer;
23 2

  
3
import java.awt.Rectangle;
4
import java.awt.geom.AffineTransform;
5
import java.awt.geom.Point2D;
6

  
7
import org.gvsig.fmap.dal.coverage.RasterLocator;
24 8
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
25 9
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
26 10
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
27 11
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
12
import org.gvsig.fmap.dal.coverage.exception.FileNotExistsException;
13
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
14
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
15
import org.gvsig.fmap.dal.coverage.exception.QueryException;
16
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
28 17
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
18
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
29 19
import org.gvsig.raster.cache.tile.TileCacheLibrary;
30 20
import org.gvsig.raster.cache.tile.provider.CacheStruct;
31 21
import org.gvsig.raster.cache.tile.provider.TileListener;
22
import org.gvsig.raster.impl.DefaultRasterManager;
23
import org.gvsig.raster.impl.buffer.cache.RasterReadOnlyBuffer;
24
import org.gvsig.raster.impl.datastruct.ExtentImpl;
25
import org.gvsig.raster.impl.store.QueryableRaster;
32 26
import org.gvsig.timesupport.Time;
33 27
import org.gvsig.tools.persistence.PersistentState;
34 28
import org.gvsig.tools.persistence.exception.PersistenceException;
......
39 33
 * 
40 34
 * @author Nacho Brodin (nachobrodin@gmail.com)
41 35
 */
42
public class DefaultRasterQuery implements RasterQuery {
36
public class DefaultRasterQuery implements RasterQuery, SpiRasterQuery {
37
	public static final int  TYPE_UNDEFINED             = -1;
43 38
	public static final int  TYPE_ENTIRE                = 0;
44
	public static final int  TYPE_COORDS                = 1;
45
	public static final int  TYPE_COORDS_SIZE           = 2;
46
	public static final int  TYPE_PX                    = 3;
47
	public static final int  TYPE_PX_SIZE               = 4;
48
	public static final int  TYPE_COORDS_SIZE_TILED     = 5;
49
	public static final int  TYPE_ONE_TILE              = 6;
50
	
51
	private int              type                       = 0;
52
	
53
	private double           x                          = 0;
54
	private double           y                          = 0;
55
	private double           w                          = 0;
56
	private double           h                          = 0;
57
	
58
	private int              pixelX                     = 0;
59
	private int              pixelY                     = 0;
60
	private int              pixelW                     = 0;
61
	private int              pixelH                     = 0;
62
	
63
	private Extent           bbox                       = null;
64
	
65
	private int              bufWidth                   = 0;
66
	private int              bufHeight                  = 0;
67
	
68
	private boolean          adjustToExtent             = true;
39
	public static final int  TYPE_WCOORDS               = 1;
40
	public static final int  TYPE_WCOORDS_RESCALED      = 2;
41
	public static final int  TYPE_WCOORDS_SHIFT         = 3;
42
	public static final int  TYPE_PX                    = 4;
43
	public static final int  TYPE_PX_RESCALED           = 5;
44
	public static final int  TYPE_PX_SHIFT              = 6;
45
	public static final int  TYPE_PX_RESCALED_SHIFT     = 7;
46
	public static final int  TYPE_TILED                 = 8;
47
	public static final int  TYPE_ONE_TILE              = 9;
48

  
49
	private int              type                       = TYPE_ENTIRE;
50
	/*
51
	 * Request in pixels
52
	 */
53
	private Rectangle        pixelWindow                = null;
54
	/*
55
	 * Request in pixels adjusted to the source. The provider will use this parameter. If the type is with
56
	 * shift then adjustedPixelWindow will be the same to the pixelWindow
57
	 */
58
	private Rectangle        adjustedPixelWindow        = null;
59
	/*
60
	 * Request in world coordinates
61
	 */
62
	private Extent           requestBoundingBox         = null;
63
	/*
64
	 * Request in world coordinates adjusted to the source. The provider will use this parameter. If the type is with
65
	 * shift then adjustedBoundingBox will be the same to the requestBoundingBox
66
	 */
67
	private Extent           adjustedBoundingBox        = null;
68

  
69
	private int              widthForResampling         = -1;
70
	private int              heightForResampling        = -1;
71
	/*
72
	 * If the request is adjusted to the input source this width is the same to widthForResampling else
73
	 * the provider has to receive the right buffer size for the request, so this adjustedWidth will
74
	 * contain a smaller buffer without frames. 
75
	 */
76
	private int              adjustedBufferWidth        = 0;
77
	/*
78
	 * If the request is adjusted to the input source this height is the same to heightForResampling else
79
	 * the provider has to receive the right buffer size for the request, so this adjustedHeight will
80
	 * contain a smaller buffer without frames. 
81
	 */
82
	private int              adjustedBufferHeight       = 0;
83

  
84
	private double[]         step                       = null;
85

  
86
	private int              tileRow                    = 0;
87
	private int              tileCol                    = 0;
88
	private int              resolutionLevel            = -1;
89
	private boolean          adjustToSrcExtent          = true;
90

  
69 91
	private int[]            drawableBands              = new int[]{0};
70 92
	private boolean          readOnly                   = false;
71 93
	private boolean          memoryBuffer               = false;
72 94
	private boolean          storeLastBuffer            = false;
73 95
	private Time             time                       = null;
96

  
74 97
	
75
	private int              resolutionLevel            = -1;
76
	
98
	private boolean			 supersamplingLoadingBuffer = false;
77 99
	/**
78
	 * Activa o desactiva el supersampleo en la carga del buffer.
79
	 */
80
	private boolean			 supersamplingLoadingBuffer = true;
81
	/**
82 100
	 * Valor NoData con el que se rellenan las celdas cuando adjustToExtent es false
83 101
	 */
84 102
	private NoData           noDataValueToFill          = null;
85
	
86
	private int              frameWidth                 = 0;
103

  
87 104
	private TileListener     listener                   = null;
88 105
	private int              alphaBandNumber            = -1;
89
	private int              tileRow                    = 0;
90
	private int              tileCol                    = 0;
106
	private boolean          dontBuildBuffer            = false;
91 107
	private CacheStruct      cacheStruct                = null;   
92 108
	private TaskStatus       taskStatus                 = null;
93
	
109

  
94 110
	//Parameters only for providers
95 111
	private BandList         bandList                   = null;
96
	private Buffer           buffer                     = null;
112
	private Buffer           bufferForProviders         = null;
113
	private boolean          forceARGBBuffer            = false;
114
	private boolean          forceRGBBuffer             = false;
115
	//private Buffer           bufferWithoutAdjust        = null;
116

  
117

  
118
	//****************************************************
119
	//*************Request of data windows****************
120
	//****************************************************
97 121
	
98
	public void setAreaOfInterest(double x, double y, double w, double h) {
99
		this.x = x;
100
		this.y = y;
101
		this.w = w;
102
		this.h = h;
103
		this.type = TYPE_COORDS;
122
	public void setAreaOfInterest() {
123
		this.type = TYPE_ENTIRE;
104 124
	}
105
	
106
	public void setAreaOfInterest(Extent bbox) {
107
		this.bbox = bbox;
108
		this.type = TYPE_COORDS;
125

  
126
	public void setAreaOfInterest(Rectangle pixelWindow) {
127
		this.pixelWindow = pixelWindow;
128
		this.type = TYPE_PX;
109 129
	}
110
	
111
	public void setAreaOfInterest(Extent bbox, int bufWidth, int bufHeight) {
112
		this.bbox = bbox;
113
		this.bufWidth = bufWidth;
114
		this.bufHeight = bufHeight;
115
		this.type = TYPE_COORDS_SIZE;
130

  
131
	public void setAreaOfInterest(Rectangle pixelWindow, int bufWidth, int bufHeight) {
132
		this.pixelWindow = pixelWindow;
133
		this.widthForResampling = bufWidth;
134
		this.heightForResampling = bufHeight;
135
		this.type = TYPE_PX;
116 136
	}
117
	
118
	public void setAreaOfInterest(Extent bbox, 
137

  
138
	public void setAreaOfInterest(Extent requestBoundingBox, int bufWidth, int bufHeight) {
139
		this.widthForResampling = bufWidth;
140
		this.heightForResampling = bufHeight;
141
		this.requestBoundingBox = requestBoundingBox;
142
		this.type = TYPE_WCOORDS;
143
	}
144

  
145
	public void setAreaOfInterest(Extent boundingBox) {
146
		this.requestBoundingBox = boundingBox;
147
		this.type = TYPE_WCOORDS;
148
	}
149

  
150
	public void setAreaOfInterest(Extent requestBoundingBox, 
119 151
			int bufWidth, int bufHeight, TileListener listener) {
120
		this.bbox = bbox;
121
		this.bufWidth = bufWidth;
122
		this.bufHeight = bufHeight;
123
		this.type = TYPE_COORDS_SIZE_TILED;
152
		this.requestBoundingBox = requestBoundingBox;
153
		this.widthForResampling = bufWidth;
154
		this.heightForResampling = bufHeight;
155
		this.type = TYPE_TILED;
124 156
		this.listener = listener;
125 157
	}
126
	
127
	public void setAreaOfInterest(int x, int y, int w, int h) {
128
		this.pixelX = x;
129
		this.pixelY = y;
130
		this.pixelW = w;
131
		this.pixelH = h;
132
		this.type = TYPE_PX;
158

  
159
	public void setTileParameters(int level, int tileCol, int tileRow) {
160
		this.type = TYPE_ONE_TILE;
161
		this.resolutionLevel = level;
162
		this.tileRow = tileRow;
163
		this.tileCol = tileCol;
133 164
	}
134
	
135
	public void setAreaOfInterest() {
136
		this.type = TYPE_ENTIRE;
137
	}
138
	
139
	public void setAreaOfInterest(int x, int y, int w, int h, int bufWidth,
140
			int bufHeight) {
141
		this.pixelX = x;
142
		this.pixelY = y;
143
		this.pixelW = w;
144
		this.pixelH = h;
145
		this.bufWidth = bufWidth;
146
		this.bufHeight = bufHeight;
147
		this.type = TYPE_PX_SIZE;
148
	}
149 165

  
166
	/**
167
	 * @deprecated Use setTileParameters(int level, int tileCol, int tileRow)
168
	 */
150 169
	public void setTileParameters(int level, int tileCol, int tileRow, Extent bbox, CacheStruct cacheStruct) {
151 170
		this.type = TYPE_ONE_TILE;
152
		this.bbox = bbox;
171
		this.requestBoundingBox = bbox;
153 172
		this.resolutionLevel = level;
154 173
		this.tileRow = tileRow;
155 174
		this.tileCol = tileCol;
......
160 179
		} else {
161 180
			size = new int[]{TileCacheLibrary.DEFAULT_TILEWIDTH, TileCacheLibrary.DEFAULT_TILEHEIGHT};
162 181
		}
163
		this.bufWidth = size[0];
164
		this.bufHeight = size[1];
182
		this.widthForResampling = size[0];
183
		this.heightForResampling = size[1];
165 184
	}
185

  
186

  
187

  
188
	//****************************************************
189
	//****************Internal Services*******************
190
	//****************************************************
166 191
	
192
	public boolean requestIsTiled() {
193
		switch (type) {
194
		case TYPE_TILED:
195
		case TYPE_ONE_TILE:
196
			return true;
197
		}
198
		return false;
199
	}
200

  
201
	public boolean requestHasShift() {
202
		switch (type) {
203
		case TYPE_PX_RESCALED_SHIFT:
204
		case TYPE_PX_SHIFT:
205
		case TYPE_WCOORDS_SHIFT:
206
			return true;
207
		}
208
		return false;
209
	}
210

  
211
	public boolean requestIsPixelCoordinates() {
212
		switch (type) {
213
		case TYPE_PX:
214
		case TYPE_PX_SHIFT:
215
		case TYPE_PX_RESCALED:
216
		case TYPE_PX_RESCALED_SHIFT:
217
		case TYPE_ENTIRE:
218
			return true;
219
		}
220
		return false;
221
	}
222

  
223
	public boolean requestIsInWorldCoordinates() {
224
		switch (type) {
225
		case TYPE_WCOORDS:
226
		case TYPE_WCOORDS_RESCALED:
227
		case TYPE_WCOORDS_SHIFT:
228
		case TYPE_TILED:
229
			return true;
230
		}
231
		return false;
232
	}
233

  
234
	public boolean requestIsRescaled() {
235
		switch (type) {
236
		case TYPE_PX_RESCALED:
237
		case TYPE_PX_RESCALED_SHIFT:
238
		case TYPE_WCOORDS_RESCALED:
239
		case TYPE_TILED:
240
			return true;
241
		}
242
		return false;
243
	}
244

  
245
	/**
246
	 * Returns true if the request is trying apply supersampling, that is, the size of the result is
247
	 * bigger that the window of maximum resolution of this source
248
	 * @return
249
	 */
250
	public boolean isSupersamplingTheRequest() {
251
		if(!requestHasShift()) {
252
			return (getBufWidth() > getAdjustedWidth() || getBufHeight() > getAdjustedHeight());
253
		}
254
		return (getAdjustedBufWidth() > getAdjustedWidth() || getAdjustedBufHeight() > getAdjustedHeight());
255
	}
256

  
257

  
258
	public RasterQuery clone() {
259
		DefaultRasterQuery q = new DefaultRasterQuery();
260
		q.type = type;
261
		q.pixelWindow = (Rectangle)pixelWindow.clone();
262
		q.adjustToSrcExtent = adjustToSrcExtent;
263
		q.widthForResampling = widthForResampling;
264
		q.heightForResampling = heightForResampling;
265
		q.requestBoundingBox = requestBoundingBox != null ? requestBoundingBox.clone() : null;
266
		q.tileCol = tileCol;
267
		q.tileRow = tileRow;
268
		q.resolutionLevel = resolutionLevel;
269
		q.readOnly = readOnly;
270
		q.memoryBuffer = memoryBuffer;
271
		q.storeLastBuffer = storeLastBuffer;
272
		if(drawableBands != null) {
273
			q.drawableBands = new int[drawableBands.length];
274
			for (int i = 0; i < q.drawableBands.length; i++) {
275
				q.drawableBands[i] = drawableBands[i];
276
			}
277
		}
278
		q.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
279
		q.noDataValueToFill = noDataValueToFill != null ? (NoData)noDataValueToFill.clone() : null;
280
		q.listener = listener;
281
		q.alphaBandNumber = alphaBandNumber;
282
		q.bandList = bandList != null ? (BandList)bandList.clone() : null;
283
		q.bufferForProviders = bufferForProviders;
284
		return q;
285
	}
286

  
287
	//****************************************************
288
	//*************Parameters calculation*****************
289
	//****************************************************
290
	
291
	/**
292
	 * Calculates the parameters using the base request. That is, bounding boxes, data windows,
293
	 * output size, steps and parameters for supersampling, band lists and buffers. This parameters
294
	 * are calculated adjusting to the source limits. For this reason, the request parameters are 
295
	 * saved in other variables, to allow calculate the displacement and resampling whether it was 
296
	 * necessary
297
	 * @param store
298
	 * @throws QueryException 
299
	 */
300
	public void calculateParameters(RasterDataStore store) throws QueryException {
301
		calculateRequestType(store);
302

  
303
		//Parameters for requests in pixels
304
		if(requestIsPixelCoordinates()) {
305
			calculateAdjustedPxSizeFromPxSize((int)store.getWidth(), (int)store.getHeight());
306
			calculateBoundingBoxesFromPxRequest(store);
307
		} 
308

  
309
		//Parameters for requests in world coordinates
310
		if(requestIsInWorldCoordinates()) {
311
			calculateAdjustedWCWindowFromWCWindow(store.getAffineTransform(), (int)store.getWidth(), (int)store.getHeight());
312
			calculatePxWindowsFromBoundingBoxes(store);
313
		}
314

  
315
		//Output
316
		calculateOutputSizeFromPxWindow(store);
317

  
318
		//Supersampling parameters
319
		step = null;
320
		if(isSupersamplingTheRequest() && !store.isRasterEnclosed()) {
321
			calculateStep(store);
322
			supersampledBuffers(store);
323
		}
324

  
325
		//Bands and buffers
326
		buildDrawableBandList(store.getBands());
327
		if(!dontBuildBuffer)
328
			createBuffer(store);
329
	}
330

  
331
	/**
332
	 * Adjust the request in world coordinates to the data size
333
	 * @param q
334
	 */
335
	private void calculateAdjustedWCWindowFromWCWindow(AffineTransform at, int w, int h) {
336
		if(requestHasShift()) {
337
			setAdjustedRequestBoundingBox(getRequestBoundingBox().clone());
338
		}
339
		RasterUtils util = RasterLocator.getManager().getRasterUtils();
340
		Extent adjustedDataExtent = util.calculateAdjustedView(getRequestBoundingBox(), at, w, h);
341
		setAdjustedRequestBoundingBox(adjustedDataExtent);
342
	}
343

  
344
	/**
345
	 * Adjust the request in pixel coordinates to the data size
346
	 * @param q
347
	 */
348
	private void calculateAdjustedPxSizeFromPxSize(int sourceWidth, int sourceHeight) {
349
		adjustedPixelWindow = (Rectangle)pixelWindow.clone();
350

  
351
		if(requestHasShift()) 
352
			return;
353

  
354
		if(getAdjustedX() < 0)
355
			setAdjustedX(0);
356
		if(getAdjustedY() < 0)
357
			setAdjustedY(0);
358
		if((getAdjustedX() + getAdjustedWidth()) > sourceWidth)
359
			setAdjustedWidth(sourceWidth - getX());
360
		if((getAdjustedY() + getAdjustedHeight()) > sourceHeight)
361
			setAdjustedHeight(sourceHeight - getAdjustedY());
362
	}
363

  
364

  
365
	private void calculateBoundingBoxesFromPxRequest(RasterDataStore store) {
366
		Extent extent = new ExtentImpl(
367
				store.rasterToWorld(new Point2D.Double(getX(), getY())),
368
				store.rasterToWorld(new Point2D.Double(getX() + getWidth(), getY() + getHeight())));
369
		setRequestBoundingBox(extent);
370

  
371
		Extent adjustedExtent = new ExtentImpl(
372
				store.rasterToWorld(new Point2D.Double(getAdjustedX(), getAdjustedY())),
373
				store.rasterToWorld(new Point2D.Double(getAdjustedX() + getAdjustedWidth(), getAdjustedY() + getAdjustedHeight())));
374
		setAdjustedRequestBoundingBox(adjustedExtent);
375
	}
376

  
377
	private double round(double value) {
378
		double a = (value - (int)value);
379
		return (a > 0.95 || a < 0.05) ? Math.round(value) : value;
380
	}
381

  
382
	private void calculateOutputSizeFromPxWindow(RasterDataStore store) {
383
		if(!requestIsRescaled()) {
384
			setBufHeight(getHeight());
385
			setBufWidth(getWidth());
386
			setAdjustedBufWidth(getAdjustedWidth());
387
			setAdjustedBufHeight(getAdjustedHeight());
388
		} else {
389
			double scaleWidth = (double)getWidth() / getBufWidth();
390
			double scaleHeight = (double)getHeight() / getBufHeight();
391
			setAdjustedBufWidth((int)Math.ceil(round(getAdjustedWidth() / scaleWidth)));
392
			setAdjustedBufHeight((int)Math.ceil(round(getAdjustedHeight() / scaleHeight)));
393
		}
394
	}
395

  
396
	private void calculatePxWindowsFromBoundingBoxes(RasterDataStore store) {
397
		Extent requestBBox = getRequestBoundingBox();
398
		Point2D ul = store.worldToRaster(requestBBox.getUL());
399
		Point2D lr = store.worldToRaster(requestBBox.getLR());
400
		int w = (int)Math.ceil(Math.abs(round(ul.getX()) - round(lr.getX())));
401
		int h = (int)Math.ceil(Math.abs(round(ul.getY()) - round(lr.getY())));
402
		Rectangle r = new Rectangle((int)ul.getX(), (int)ul.getY(), w, h);
403
		pixelWindow = r;
404

  
405
		Extent adjustedBBox = getAdjustedRequestBoundingBox();
406
		ul = store.worldToRaster(adjustedBBox.getUL());
407
		lr = store.worldToRaster(adjustedBBox.getLR());
408
		w = (int)Math.ceil(Math.abs(round(ul.getX()) - round(lr.getX())));
409
		h = (int)Math.ceil(Math.abs(round(ul.getY()) - round(lr.getY())));
410
		r = new Rectangle((int)ul.getX(), (int)ul.getY(), w, h);
411
		adjustedPixelWindow = r;
412
	}
413

  
414
	/**
415
	 * <p>
416
	 * If the request is being supersampled, then the buffer size will be bigger than the pixel window. 
417
	 * In this case the provider will receive a buffer in 1:1 scale. The supersampling function will be 
418
	 * in the client (supersampling deactivated) or in the store (supersampling activated). 
419
	 * </p><p>
420
	 * The buffer will have one pixel more because the resampling cuts the first pixel by the beginning and
421
	 * shows the last pixel by the end.
422
	 * </p>
423
	 * @param store
424
	 */
425
	private void supersampledBuffers(RasterDataStore store) {
426
		//Si se est? pidiendo supersampleo el provider tiene que recibir un buffer de tama?o igual al n?mero real de
427
		//pixels del ?rea, por ello habr? que cambiar el adjustedbufwidth y adjustedBufHeight. Adem?s habr? que variar
428
		//el extent del provider y la ventana en pixeles para que todo cuadre. El objetivo es que cuando el cliente (Render)
429
		//supersamplee no le queden huecos en blanco porque le falte el ?ltimo pixel.
430
		if((getAdjustedX() + getAdjustedWidth()) < store.getWidth())
431
			setAdjustedWidth(getAdjustedWidth() + 1);
432
		if((getAdjustedY() + getAdjustedHeight()) < store.getHeight())
433
			setAdjustedHeight(getAdjustedHeight() + 1);
434
		setAdjustedBufWidth(getAdjustedWidth());
435
		setAdjustedBufHeight(getAdjustedHeight());
436
		Point2D ul = store.rasterToWorld(new Point2D.Double(adjustedPixelWindow.getX(), adjustedPixelWindow.getY()));
437
		Point2D lr = store.rasterToWorld(new Point2D.Double(
438
				adjustedPixelWindow.getX() + adjustedPixelWindow.getWidth(), 
439
				adjustedPixelWindow.getY() + adjustedPixelWindow.getHeight()));
440
		setAdjustedRequestBoundingBox(new ExtentImpl(ul, lr));
441
	}
442

  
443
	/**
444
	 * Giving a world coordinates, a buffer size and a original raster size. If the 
445
	 * buffer is bigger than the window requested in the source raster (supersampling), 
446
	 * then it means that each pixel of the raster will be written several times in 
447
	 * the destination buffer.
448
	 * 
449
	 * This function calculates the shift in pixels en X and Y coordinate that 
450
	 * correspond to the first pixel, due to this pixel won't be drawn entirely.
451
	 * 
452
	 * This operation is needed when the client wants to apply suppersampling on the 
453
	 * result of a request.
454
	 */
455
	private void calculateStep(RasterDataStore store) {
456
		Point2D tl = store.worldToRaster(getAdjustedRequestBoundingBox().getUL());
457
		Point2D br = store.worldToRaster(getAdjustedRequestBoundingBox().getLR());
458

  
459
		//Se obtiene el tama?o de la petici?n original pero ajustada ya que adjustedBufferWidth y adjustedBufferHeight
460
		//habr?n sido modificados para que no excedan el tama?o de la ventana, ya que el provider no debe supersamplear
461
		double scaleWidth = (double)getWidth() / getBufWidth();
462
		double scaleHeight = (double)getHeight() / getBufHeight();
463
		int srcOriginalAdjustedWidth = (int)Math.ceil(round(getAdjustedWidth() / scaleWidth));
464
		int srcOriginalAdjustedHeight = (int)Math.ceil(round(getAdjustedHeight() / scaleHeight));
465

  
466
		double wPx = (srcOriginalAdjustedWidth / Math.abs(br.getX() - tl.getX()));
467
		double hPx = (srcOriginalAdjustedHeight / Math.abs(br.getY() - tl.getY()));
468

  
469
		int x = (int)((tl.getX() > br.getX()) ? Math.floor(br.getX()) : Math.floor(tl.getX()));
470
		int y = (int)((tl.getY() > br.getY()) ? Math.floor(br.getY()) : Math.floor(tl.getY()));
471

  
472
		double a = (tl.getX() > br.getX()) ? (Math.abs(br.getX() - x)) : (Math.abs(tl.getX() - x));
473
		double b = (tl.getY() > br.getY()) ? (Math.abs(br.getY() - y)) : (Math.abs(tl.getY() - y));
474

  
475
		double stpX = (int)((a * srcOriginalAdjustedWidth) / Math.abs(br.getX() - tl.getX()));
476
		double stpY = (int)((b * srcOriginalAdjustedHeight) / Math.abs(br.getY() - tl.getY()));
477

  
478
		step = new double[]{stpX, stpY, wPx, hPx};
479
	}
480

  
481
	public Buffer createBuffer(RasterDataStore store) throws QueryException {
482
		if(isReadOnly()) {
483
			bufferForProviders = DefaultRasterManager.getInstance().createReadOnlyBuffer(
484
					store.getDataType()[0], getAdjustedBufWidth(), getAdjustedBufHeight(), store.getBandCount());
485
			try {
486
				((RasterReadOnlyBuffer)bufferForProviders).setBufferParams((QueryableRaster)store, 
487
						getAdjustedX(), 
488
						getAdjustedY(), 
489
						getAdjustedX() + getAdjustedWidth() - 1, 
490
						getAdjustedY() + getAdjustedHeight() - 1, 
491
						bandList);
492
			} catch (FileNotExistsException e) {
493
				throw new QueryException("Error setting buffer params in a RO buffer", e);
494
			} catch (NotSupportedExtensionException e) {
495
				throw new QueryException("Error setting buffer params in a RO buffer", e);
496
			} catch (InvalidSetViewException e) {
497
				throw new QueryException("Error setting buffer params in a RO buffer", e);
498
			}
499
		} else {
500
			BandList bandList = buildDrawableBandList(store.getBands());
501
			int bandCount = bandList.getDrawableBandsCount();
502
			if(forceARGBBuffer) 
503
				bandCount = 4;
504
			if(forceRGBBuffer) 
505
				bandCount = 3;
506
			
507
			if(isMemoryBuffer()) 
508
				bufferForProviders = DefaultRasterManager.getInstance().createMemoryBuffer(
509
						store.getDataType()[0], getAdjustedBufWidth(), getAdjustedBufHeight(), bandCount, true);
510
			else
511
				bufferForProviders = DefaultRasterManager.getInstance().createBuffer(
512
						store.getDataType()[0], getAdjustedBufWidth(), getAdjustedBufHeight(), bandCount, true);
513
		}
514

  
515
		bufferForProviders.setDataExtent(getAdjustedRequestBoundingBox().toRectangle2D());
516
		return bufferForProviders;
517

  
518
	}
519

  
520
	/**
521
	 * Builds a list o bands to draw from the store band list and
522
	 * the <code>drawablebands</code> asigned by the user
523
	 * @param drawableBands
524
	 * @param storeBandList
525
	 * @return
526
	 */
527
	public BandList buildDrawableBandList(BandList storeBandList) {
528
		bandList = (BandList)storeBandList.clone();
529
		//If drawableBands is null then the bandList is the same that the source band list
530
		if(drawableBands != null)
531
			bandList.setDrawableBands(drawableBands);
532
		return bandList;
533
	}
534
	
535
	private boolean isAdjustingPixelWindowToStore(RasterDataStore store) {
536
		return (pixelWindow.getX() >= 0 && 
537
				pixelWindow.getY() >= 0 && 
538
				pixelWindow.getWidth() <= store.getWidth() && 
539
				pixelWindow.getHeight() <= store.getHeight());
540
	}
541
	
542
	private boolean isBufferSizeDefined() {
543
		return (widthForResampling != -1 && heightForResampling != -1);
544
	}
545
	
546
	private boolean isAdjustingRequestBBoxToStore(RasterDataStore store) {
547
		Extent intersection = requestBoundingBox.intersection(store.getExtent());
548
		return intersection.equals(store.getExtent());
549
	}
550
	
551
	private void calculateRequestType(RasterDataStore store) {
552
		if(type == TYPE_ENTIRE) {
553
			pixelWindow = new Rectangle(0, 0, (int)store.getWidth(), (int)store.getHeight());
554
			return;
555
		}
556
		
557
		if(!adjustToSrcExtent) {
558
			if(type == TYPE_PX) {
559
				if(isAdjustingPixelWindowToStore(store)) {
560
					if(isBufferSizeDefined())
561
						this.type = TYPE_PX_RESCALED;
562
					else
563
						this.type = TYPE_PX;
564
				} else {
565
					if(isBufferSizeDefined())
566
						this.type = TYPE_PX_RESCALED_SHIFT;
567
					else
568
						this.type = TYPE_PX_SHIFT;
569
				}
570
			}
571
			if(type == TYPE_WCOORDS) {
572
				if(isBufferSizeDefined()) {
573
					if(isAdjustingRequestBBoxToStore(store))
574
						this.type = TYPE_WCOORDS_RESCALED;
575
					else
576
						this.type = TYPE_WCOORDS_SHIFT;						
577
				} //else TYPE_WCOORDS
578
			}
579
		} else {
580
			if(type == TYPE_PX) {
581
				if(isBufferSizeDefined())
582
					this.type = TYPE_PX_RESCALED;
583
			}
584
			if(type == TYPE_WCOORDS) {
585
				if(isBufferSizeDefined())
586
					this.type = TYPE_WCOORDS_RESCALED;
587
				//else TYPE_WCOORDS
588
			}
589
		}
590
	}
591

  
592
	//****************************************************
593
	//*********Implementing DataQuery methods*************
594
	//****************************************************
595

  
596
	public Object getQueryParameter(String name) {
597
		return null;
598
	}
599

  
600
	public double getScale() {
601
		return 0;
602
	}
603

  
604
	public void setQueryParameter(String name, Object value) {
605

  
606
	}
607

  
608
	public void setScale(double scale) {
609

  
610
	}
611

  
612
	//****************************************************
613
	//*********Implementing Persistent methods************
614
	//****************************************************
615

  
616
	public void loadFromState(PersistentState state)
617
			throws PersistenceException {
618

  
619
	}
620

  
621
	public void saveToState(PersistentState state) throws PersistenceException {
622

  
623
	}
624

  
625
	//****************************************************
626
	//**************Getters and Setters*******************
627
	//****************************************************
628
	
629
	public void forceARGBRequest() {
630
		this.forceARGBBuffer = true;
631
		this.forceRGBBuffer = false;
632
	}
633
	
634
	public void forceRGBRequest() {
635
		this.forceRGBBuffer = true;
636
		this.forceARGBBuffer = false;
637
	}
638
	
639
	public boolean isforcingRGBRequest() {
640
		return (forceRGBBuffer && !forceARGBBuffer);
641
	}
642
	
643
	public boolean isforcingARGBRequest() {
644
		return (forceARGBBuffer && !forceRGBBuffer);
645
	}
646
	
647
	public void dontBuildBuffer() {
648
		this.dontBuildBuffer = true;
649
	}
650

  
651
	public int getType() {
652
		return type;
653
	}
654

  
167 655
	public void storeLastBuffer(boolean store) {
168 656
		this.storeLastBuffer = store;
169 657
	}
170
	
658

  
171 659
	/**
172 660
	 * The user can told if the buffer will be stored or not in the RasterDatasource.
173 661
	 * @return store
......
177 665
	}
178 666

  
179 667
	public void setAdjustToExtent(boolean adjustToExtent) {
180
		this.adjustToExtent = adjustToExtent;
668
		this.adjustToSrcExtent = adjustToExtent;
181 669
	}
182
	
670

  
183 671
	public boolean isAdjustToExtent() {
184
		return adjustToExtent;
672
		return adjustToSrcExtent;
185 673
	}
186
	
674

  
187 675
	public int[] getDrawableBands() {
188 676
		return drawableBands;
189 677
	}
......
199 687
	public void setReadOnly(boolean readOnly) {
200 688
		this.readOnly = readOnly;
201 689
	}
202
	
203
	public boolean isSupersamplingLoadingBuffer() {
690

  
691
	/**
692
	 * Returns true if the supersampling is enable and false if it is disable
693
	 * Rendering from gvSIG, the resampling is always disable because if the request 
694
	 * is greater than 1:1 scale the resampling will be done in the client <code>Render</code>.
695
	 * The default value is disable.
696
	 */
697
	public boolean isSupersamplingOptionActive() {
204 698
		return supersamplingLoadingBuffer;
205 699
	}
206 700

  
207
	public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
701
	/**
702
	 * Enables or disables the supersampling loading the buffer. Rendering from gvSIG,
703
	 * the resampling is always disable because if the request is greater than 1:1 scale
704
	 * the resampling will be done in the client <code>Render</code>
705
	 */
706
	public void setSupersamplingOption(boolean supersamplingLoadingBuffer) {
208 707
		this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
209 708
	}
210
	
709

  
211 710
	public void setMemoryBuffer(boolean memoryBuffer) {
212 711
		this.memoryBuffer = memoryBuffer;
213 712
	}
214
	
713

  
215 714
	/**
216 715
	 * Obtiene el flag que dice si la carga del siguiente buffer es en memoria
217 716
	 * @return memory true si la siguiente carga de buffer se hace en memoria y false se deja decidir al dataset 
......
220 719
	public boolean isMemoryBuffer() {
221 720
		return memoryBuffer;
222 721
	}
223
	
722

  
224 723
	public void setNoDataToFill(NoData noData) {
225 724
		this.noDataValueToFill = noData;
226 725
	}
227
	
726

  
228 727
	public void setAlphaBand(int bandNumber) {
229 728
		this.alphaBandNumber = bandNumber;
230 729
	}
231
	
232
	public void setFrameWidth(int n) {
233
		this.frameWidth = n;
234
	}
235
	
730

  
236 731
	public int getAlphaBandNumber() {
237 732
		return alphaBandNumber;
238 733
	}
239
	
734

  
240 735
	public NoData getNoDataValueToFill() {
241 736
		return this.noDataValueToFill;
242 737
	}
243

  
244
	public int getType() {
245
		return type;
246
	}
247 738
	
248
	public void setType(int type) {
249
		this.type = type;
739
	public void setRequestPixelWindow(Rectangle pixelWindow) {
740
		this.pixelWindow = pixelWindow;
250 741
	}
251 742

  
252
	public double getX() {
253
		return x;
743
	public int getX() {
744
		return (int)pixelWindow.getX();
254 745
	}
255 746

  
256
	public double getY() {
257
		return y;
747
	public int getY() {
748
		return (int)pixelWindow.getY();
258 749
	}
259 750

  
260
	public double getW() {
261
		return w;
751
	public int getWidth() {
752
		return (int)pixelWindow.getWidth();
262 753
	}
263 754

  
264
	public double getH() {
265
		return h;
755
	public int getHeight() {
756
		return (int)pixelWindow.getHeight();
266 757
	}
267 758

  
268
	public int getPixelX() {
269
		return pixelX;
759
	public void setX(int x) {
760
		pixelWindow.setLocation(x, getY());
270 761
	}
271 762

  
272
	public int getPixelY() {
273
		return pixelY;
763
	public void setY(int y) {
764
		pixelWindow.setLocation(getX(), y);
274 765
	}
275 766

  
276
	public int getPixelW() {
277
		return pixelW;
767
	public void setWidth(int w) {
768
		pixelWindow.setSize(w, getWidth());
278 769
	}
279 770

  
280
	public int getPixelH() {
281
		return pixelH;
771
	public void setHeight(int h) {
772
		pixelWindow.setSize(getHeight(), h);
282 773
	}
283
	
284
	public void setPixelX(int x) {
285
		pixelX = x;
286
	}
287 774

  
288
	public void setPixelY(int y) {
289
		pixelY = y;
775
	public int getAdjustedX() {
776
		return (int)adjustedPixelWindow.getX();
290 777
	}
291 778

  
292
	public void setPixelW(int w) {
293
		pixelW = w;
779
	public int getAdjustedY() {
780
		return (int)adjustedPixelWindow.getY();
294 781
	}
295 782

  
296
	public void setPixelH(int h) {
297
		pixelH = h;
783
	public int getAdjustedWidth() {
784
		return (int)adjustedPixelWindow.getWidth();
298 785
	}
299 786

  
300
	public Extent getBBox() {
301
		return bbox;
787
	public int getAdjustedHeight() {
788
		return (int)adjustedPixelWindow.getHeight();
302 789
	}
303
	
304
	public void setBBox(Extent bbox) {
305
		this.bbox = bbox;
306
	}
307 790

  
308
	public int getBufWidth() {
309
		return bufWidth;
791
	public void setAdjustedX(int x) {
792
		adjustedPixelWindow.setLocation(x, getAdjustedY());
310 793
	}
311 794

  
312
	public int getBufHeight() {
313
		return bufHeight;
795
	public void setAdjustedY(int y) {
796
		adjustedPixelWindow.setLocation(getAdjustedX(), y);
314 797
	}
315
	
316
	public void setBufHeight(int h) {
317
		bufHeight = h;
318
	}
319
	
320
	public void setBufWidth(int w) {
321
		bufWidth = w;
322
	}
323 798

  
324
	public boolean isReadOnly() {
325
		return readOnly;
799
	public void setAdjustedWidth(int w) {
800
		adjustedPixelWindow.setSize(w, getAdjustedHeight());
326 801
	}
327
	
328
	public int getFrameWidth() {
329
		return frameWidth;
330
	}
331 802

  
332
	public TileListener getTileListener() {
333
		return listener;
803
	public void setAdjustedHeight(int h) {
804
		adjustedPixelWindow.setSize(getAdjustedWidth(), h);
334 805
	}
335
	
336
	public void setTileListener(TileListener listener) {
337
		this.listener = listener;
338
	}
339
	
340
	public Time getTime() {
341
		return time;
342
	}
343 806

  
344
	public void setTime(Time time) {
345
		this.time = time;
346
	}
347
	
348
	public int getTileRow() {
349
		return tileRow;
350
	}
807
	/**
808
	 * Gets the window of the request in pixel coordinates
809
	 */
810
	 public Rectangle getRequestPxWindow() {
811
		 return pixelWindow;
812
	 }
351 813

  
352
	public int getTileCol() {
353
		return tileCol;
354
	}
814
	 /**
815
	  * Gets the adjusted window of the request in pixel coordinates
816
	  */
817
	 public Rectangle getAdjustedRequestPxWindow() {
818
		 return adjustedPixelWindow;
819
	 }
355 820

  
356
	public CacheStruct getCacheStruct() {
357
		return cacheStruct;
358
	}
359
	
360
	public void setCacheStruct(CacheStruct cacheStruct) {
361
		this.cacheStruct = cacheStruct;
362
	}
821
	 /**
822
	  * Gets a bounding box of a request in world coordinates.
823
	  */
824
	 public Extent getRequestBoundingBox() {
825
		 return requestBoundingBox;
826
	 }
363 827

  
364
	public int getResolutionLevel() {
365
		return resolutionLevel;
366
	}
367
	
368
	public void setTaskStatus(TaskStatus taskStatus) {
369
		this.taskStatus = taskStatus;
370
	}
371
	
372
	/**
373
	 * Gets the task status
374
	 */
375
	public TaskStatus getTaskStatus() {
376
		return taskStatus;
377
	}
378
	
379
	//****************************************************
380
	//*********Parameters only for providers**************
381
	//****************************************************
382
	
383
	public BandList getBandList() {
384
		return bandList;
385
	}
828
	 /**
829
	  * Sets a bounding box of a request in world coordinates.
830
	  * @param requestBoundingBox
831
	  */
832
	 public void setRequestBoundingBox(Extent requestBoundingBox) {
833
		 this.requestBoundingBox = requestBoundingBox;
834
	 }
386 835

  
387
	public void setBandList(BandList bandList) {
388
		this.bandList = bandList;
389
	}
836
	 /**
837
	  * Gets a bounding box of a request in world coordinates adjusted to the bounding box of the source.
838
	  */
839
	 public Extent getAdjustedRequestBoundingBox() {
840
		 return adjustedBoundingBox;
841
	 }
390 842

  
391
	public Buffer getBuffer() {
392
		return buffer;
393
	}
843
	 /**
844
	  * Sets a bounding box of a request in world coordinates adjusted to the bounding box of the source.
845
	  * @param requestBoundingBox
846
	  */
847
	 public void setAdjustedRequestBoundingBox(Extent adjustedBoundingBox) {
848
		 this.adjustedBoundingBox = adjustedBoundingBox;
849
	 }
394 850

  
395
	public void setBuffer(Buffer buffer) {
396
		this.buffer = buffer;
397
	}
398
	
399
	//****************************************************
400
	//*********Implementing DataQuery methods*************
401
	//****************************************************
402
	
403
	public Object getQueryParameter(String name) {
404
		// TODO Auto-generated method stub
405
		return null;
406
	}
851
	 public int getBufWidth() {
852
		 return widthForResampling;
853
	 }
407 854

  
408
	public double getScale() {
409
		// TODO Auto-generated method stub
410
		return 0;
411
	}
855
	 public int getBufHeight() {
856
		 return heightForResampling;
857
	 }
412 858

  
413
	public void setQueryParameter(String name, Object value) {
414
		// TODO Auto-generated method stub
415
		
416
	}
859
	 public void setBufHeight(int h) {
860
		 heightForResampling = h;
861
	 }
417 862

  
418
	public void setScale(double scale) {
419
		// TODO Auto-generated method stub
420
		
421
	}
422
	
423
	//****************************************************
424
	//*********Implementing Persistent methods************
425
	//****************************************************
863
	 public void setBufWidth(int w) {
864
		 widthForResampling = w;
865
	 }
426 866

  
427
	public void loadFromState(PersistentState state)
428
			throws PersistenceException {
429
		// TODO Auto-generated method stub
430
		
431
	}
867
	 public int getAdjustedBufWidth() {
868
		 return adjustedBufferWidth;
869
	 }
432 870

  
433
	public void saveToState(PersistentState state) throws PersistenceException {
434
		// TODO Auto-generated method stub
435
		
436
	}
871
	 public int getAdjustedBufHeight() {
872
		 return adjustedBufferHeight;
873
	 }
874

  
875
	 public void setAdjustedBufHeight(int h) {
876
		 adjustedBufferHeight = h;
877
	 }
878

  
879
	 public void setAdjustedBufWidth(int w) {
880
		 adjustedBufferWidth = w;
881
	 }
882

  
883
	 public boolean isReadOnly() {
884
		 return readOnly;
885
	 }
886

  
887
	 public TileListener getTileListener() {
888
		 return listener;
889
	 }
890

  
891
	 public void setTileListener(TileListener listener) {
892
		 this.listener = listener;
893
	 }
894

  
895
	 public Time getTime() {
896
		 return time;
897
	 }
898

  
899
	 public void setTime(Time time) {
900
		 this.time = time;
901
	 }
902

  
903
	 public int getTileRow() {
904
		 return tileRow;
905
	 }
906

  
907
	 public int getTileCol() {
908
		 return tileCol;
909
	 }
910

  
911
	 public CacheStruct getCacheStruct() {
912
		 return cacheStruct;
913
	 }
914

  
915
	 public void setCacheStruct(CacheStruct cacheStruct) {
916
		 this.cacheStruct = cacheStruct;
917
	 }
918

  
919
	 public int getResolutionLevel() {
920
		 return resolutionLevel;
921
	 }
922

  
923
	 public void setTaskStatus(TaskStatus taskStatus) {
924
		 this.taskStatus = taskStatus;
925
	 }
926

  
927
	 public BandList getBandList() {
928
		 return bandList;
929
	 }
930

  
931
	 public void setBandList(BandList bandList) {
932
		 this.bandList = bandList;
933
	 }
934

  
935
	 /**
936
	  * Buffer loaded by the provider and created by the store
937
	  * @return
938
	  */
939
	 public Buffer getBufferForProviders() {
940
		 return bufferForProviders;
941
	 }
942
	 
943
	 public void setBufferResult(Buffer buffer) {
944
		 this.bufferForProviders = buffer;
945
	 }
946

  
947
	 public void setBufferForProviders(Buffer buffer) throws QueryException {
948
		 if(buffer.getWidth() != getAdjustedBufWidth() || buffer.getHeight() != getAdjustedBufHeight())
949
			 throw new QueryException("Error in buffer size");
950
		 this.bufferForProviders = buffer;
951
	 }
952

  
953
	 public double[] getStep() {
954
		 return step;
955
	 }
956

  
957
	 /**
958
	  * Gets the task status
959
	  */
960
	 public TaskStatus getTaskStatus() {
961
		 return taskStatus;
962
	 }
437 963
}

Also available in: Unified diff