Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / grid / render / Rendering.java @ 18279

History | View | Annotate | Download (21.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.grid.render;
20

    
21
import java.awt.Dimension;
22
import java.awt.Graphics2D;
23
import java.awt.Image;
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27

    
28
import org.gvsig.raster.buffer.BufferFactory;
29
import org.gvsig.raster.dataset.IBuffer;
30
import org.gvsig.raster.dataset.IRasterDataSource;
31
import org.gvsig.raster.dataset.InvalidSetViewException;
32
import org.gvsig.raster.dataset.io.RasterDriverException;
33
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
34
import org.gvsig.raster.datastruct.Extent;
35
import org.gvsig.raster.datastruct.ViewPortData;
36
import org.gvsig.raster.grid.Grid;
37
import org.gvsig.raster.grid.GridTransparency;
38
import org.gvsig.raster.grid.filter.RasterFilter;
39
import org.gvsig.raster.grid.filter.RasterFilterList;
40
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
41
import org.gvsig.raster.util.RasterUtilities;
42
/**
43
 * Esta clase se encarga de la gesti?n del dibujado de datos le?dos desde la capa
44
 * "dataaccess" sobre objetos java. Para ello necesita una fuente de datos que tipicamente
45
 * es un buffer (RasterBuffer) y un objeto que realice la funci?n de escritura de datos a
46
 * partir de un estado inicial.
47
 * Esta capa del renderizado gestiona Extents, rotaciones, tama?os de vista pero la escritura
48
 * de datos desde el buffer al objeto image es llevada a cabo por ImageDrawer.
49
 *
50
 * Par?metros de control de la visualizaci?n:
51
 * <UL>
52
 * <LI>renderBands: Orden de visualizado de las bands.</LI>
53
 * <LI>replicateBands: Para visualizaci?n de raster de una banda. Dice si se replica sobre las otras dos bandas
54
 * de visualizaci?n o se ponen a 0.</LI>
55
 * <LI>enhanced: aplicaci?n de filtro de realce</LI>
56
 * <LI>removeEnds: Eliminar extremos en el filtro de realce. Uso del segundo m?ximo y m?nimo</LI>
57
 * <LI>tailTrim: Aplicacion de recorte de colas en el realce. Es un valor decimal que representa el porcentaje del recorte entre 100.
58
 * Es decir, 0.1 significa que el recorte es de un 10%</LI>
59
 * </UL>
60
 *
61
 * @author Nacho Brodin (nachobrodin@gmail.com)
62
 */
63
public class Rendering {
64

    
65
        /**
66
         * Grid para la gesti?n del buffer
67
         */
68
        private Grid             grid             = null;
69
        /**
70
         * Fuente de datos para el renderizado
71
         */
72
        private BufferFactory    bufferFactory    = null;
73
        /**
74
         * Objeto sobre el cual se hace el renderizado
75
         */
76
        private Image            geoImage         = null;
77
        /**
78
         * N?mero de bandas a renderizar y en el orden que se har?. Esto es asignado
79
         * por el usuario de la renderizaci?n.
80
         */
81
        private int[]            renderBands      = { 0, 1, 2 };
82
        /**
83
         * Tiene el comportamiento cuando se tiene un raster con una. Dice si en las
84
         * otras bandas a renderizar se replica la banda existente o se ponen a 0.
85
         */
86
        private boolean          replicateBand    = false;
87

    
88
        private ImageDrawer      drawer           = null;
89
        /**
90
         * Ultima transparencia aplicada en la visualizaci?n que es obtenida desde el
91
         * grid
92
         */
93
        private GridTransparency lastTransparency = null;
94
        /**
95
         * Lista de filtros aplicada en la renderizaci?n
96
         */
97
        private RasterFilterList filterList       = null;
98

    
99
        private IBuffer          lastRenderBuffer = null;
100

    
101
        /**
102
         * Ancho y alto del objeto Image en una petici?n de dibujado a un raster
103
         * raster
104
         */
105
        private double           widthImage, heightImage;
106

    
107
        private Point2D          ulPxRequest, lrPxRequest;
108

    
109
        /**
110
         * Constructor
111
         */
112
        public Rendering() {
113
                init();
114
        }
115

    
116
        /**
117
         * Constructor
118
         * @param grid
119
         */
120
        public Rendering(Grid grid) {
121
                this.grid = grid;
122
                init();
123
        }
124

    
125
        /**
126
         * Constructor
127
         * @param grid
128
         */
129
        public Rendering(BufferFactory ds) {
130
                this.bufferFactory = ds;
131
                init();
132
        }
133

    
134
        private void init(){
135
                drawer = new ImageDrawer(this);
136

    
137
                //Bandas que se dibujan por defecto si la interpretaci?n de color no tiene valores
138
                if (bufferFactory != null && bufferFactory.getDataSource().getBandCount() == 1)
139
                        setRenderBands(new int[] { 0, 0, 0 });
140
                else if (bufferFactory != null && bufferFactory.getDataSource().getBandCount() == 2)
141
                        setRenderBands(new int[] { 0, 1, 1 });
142
                else
143
                        setRenderBands(new int[] { 0, 1, 2 });
144
                        
145
                //---------------------------------------------------
146
                //INICIALIZACI?N DE LA INTERPRETACI?N DE COLOR
147

    
148
                //Inicializaci?n de la asignaci?n de bandas en el renderizado
149
                //Leemos el objeto metadata para obtener la interpretaci?n de color asociada al raster
150
                if (bufferFactory != null && bufferFactory.getDataSource().getDatasetCount() == 1) {
151
                        DatasetColorInterpretation colorInterpr = bufferFactory.getDataSource().getDataset(0)[0].getColorInterpretation();
152
                        if (colorInterpr != null) {
153
                                if (colorInterpr.getBand(DatasetColorInterpretation.PAL_BAND) == -1) {
154
                                        if(colorInterpr.isUndefined()) 
155
                                                return;
156
                                        int[] result = new int[]{-1, -1, -1};
157
                                        int gray = colorInterpr.getBand(DatasetColorInterpretation.GRAY_BAND);
158
                                        if(gray != -1) {
159
                                                result[0] = result[1] = result[2] = gray;
160
                                        } else {
161
                                                int r = colorInterpr.getBand(DatasetColorInterpretation.RED_BAND);
162
                                                if ( r != -1) 
163
                                                        result[0] = r;
164
                                                int g = colorInterpr.getBand(DatasetColorInterpretation.GREEN_BAND);
165
                                                if ( g != -1) 
166
                                                        result[1] = g; 
167
                                                int b = colorInterpr.getBand(DatasetColorInterpretation.BLUE_BAND);
168
                                                if ( b != -1) 
169
                                                        result[2] = b; 
170
                                        }
171
                                        setRenderBands(result);
172
                                }
173
                        }
174
                }
175
        }
176

    
177
        /**
178
         * Dibuja el raster sobre el Graphics. Para ello debemos de pasar el viewPort que corresponde a la
179
         * vista. Este viewPort es ajustado a los tama?os m?ximos y m?nimos de la imagen por la funci?n
180
         * calculateNewView. Esta funci?n tambi?n asignar? la vista a los drivers. Posteriormente se calcula
181
         * el alto y ancho de la imagen a dibujar (wImg, hImg), as? como el punto donde se va a pintar dentro
182
         * del graphics (pt). Finalmente se llama a updateImage del driver para que pinte y una vez dibujado
183
         * se pasa a trav?s de la funci?n renderizeRaster que es la encargada de aplicar la pila de filtros
184
         * sobre el Image que ha devuelto el driver.
185
         *
186
         * Para calcular en que coordenada pixel (pt) se empezar? a pintar el BufferedImage con el raster le?do
187
         * se aplica sobre la esquina superior izquierda de esta la matriz de transformaci?n del ViewPortData
188
         * pasado vp.mat.transform(pt, pt). Si el raster no est? rotado este punto es el resultante de la
189
         * funci?n calculateNewView que devuelve la petici?n ajustada al extent de la imagen (sin rotar). Si
190
         * el raster est? rotado necesitaremos para la transformaci?n el resultado de la funci?n coordULRotateRaster.
191
         * Lo que hace esta ?ltima es colocar la petici?n que ha sido puesta en coordenadas de la imagen sin rotar
192
         * (para pedir al driver de forma correcta) otra vez en coordenadas de la imagen rotada (para calcular su
193
         * posici?n de dibujado).
194
         *
195
         * Para dibujar sobre el Graphics2D el raster rotado aplicaremos la matriz de transformaci?n con los
196
         * par?metros de Shear sobre este Graphics de forma inversa. Como hemos movido el fondo tendremos que
197
         * recalcular ahora el punto donde se comienza a dibujar aplicandole la transformaci?n sobre este
198
         * at.inverseTransform(pt, pt);. Finalmente volcamos el BufferedImage sobre el Graphics volviendo a dejar
199
         * el Graphics en su posici?n original al acabar.
200
         *
201
         * @param g Graphics sobre el que se pinta
202
         * @param vp ViewPort de la extensi?n a dibujar
203
         * @throws InvalidSetViewException
204
         * @throws ArrayIndexOutOfBoundsException
205
         */
206
        public synchronized Image draw(Graphics2D g, ViewPortData vp)
207
                throws RasterDriverException, InvalidSetViewException, InterruptedException {
208
                geoImage = null;
209
                IRasterDataSource dataset = bufferFactory.getDataSource();
210
                AffineTransform transf = dataset.getAffineTransform();
211

    
212
                if(RasterUtilities.isOutside(vp.getExtent(), dataset.getExtent()))
213
                        return null;
214

    
215
                Extent adjustedRotedRequest = request(vp, dataset);
216

    
217
                if ((widthImage <= 0) || (heightImage <= 0))
218
                        return null;
219

    
220
                double[] step = null;
221

    
222
                if (bufferFactory != null) {
223
                        if (lastTransparency == null)
224
                                lastTransparency = new GridTransparency(bufferFactory.getDataSource().getTransparencyFilesStatus());
225
                        // Asignamos la banda de transparencia si existe esta
226
                        if (bufferFactory.getDataSource().getTransparencyFilesStatus().existAlphaBand()) {
227
                                // BufferFactory bufferFactoryAlphaBand = new BufferFactory(bufferFactory.getMultiRasterDataset());
228
                                bufferFactory.setSupersamplingLoadingBuffer(false); // Desactivamos el supersampleo en la carga del buffer.
229
                                bufferFactory.setDrawableBands(new int[] { lastTransparency.getAlphaBandNumber(), -1, -1 });
230
                                bufferFactory.setAreaOfInterest(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY(), adjustedRotedRequest.getLRX(), adjustedRotedRequest.getLRY(), (int)Math.round(widthImage), (int)Math.round(heightImage));
231
                                bufferFactory.setSupersamplingLoadingBuffer(true);
232
                                lastTransparency.setAlphaBand(bufferFactory.getRasterBuf());
233
                                lastTransparency.activeTransparency();
234
                        }
235
                        bufferFactory.setSupersamplingLoadingBuffer(false); // Desactivamos el supersampleo en la carga del buffer.
236
                        // En el renderizado ser? ImageDrawer el que se encargue de esta funci?n
237
                        bufferFactory.setDrawableBands(getRenderBands());
238
                        step = bufferFactory.setAreaOfInterest(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY(), adjustedRotedRequest.getLRX(), adjustedRotedRequest.getLRY(), (int)Math.round(widthImage), (int)Math.round(heightImage));
239
                        bufferFactory.setSupersamplingLoadingBuffer(true);
240

    
241
                } else
242
                        return null;
243

    
244
                grid = new Grid(bufferFactory, true);
245
                filterList.addEnvParam("Transparency", lastTransparency);
246
                grid.setFilterList(filterList);
247

    
248
                grid.applyFilters();
249

    
250
                // Objeto con la info de paleta
251
                lastRenderBuffer = grid.getRasterBuf();
252
                drawer.setBuffer(lastRenderBuffer); // Buffer de datos a renderizar
253
                drawer.setStep(step); // Desplazamiento para supersampleo
254
                drawer.setBufferSize((int)Math.round(widthImage), (int)Math.round(heightImage)); // Ancho y alto del buffer
255
                geoImage = drawer.drawBufferOverImageObject(replicateBand, getRenderBands()); // Acci?n de renderizado
256

    
257
                //En el caso de no tenga rotaci?n y el tama?o de pixel sea positivo en X y negativo en Y no aplicamos ninguna
258
                //transformaci?n. Esto no es necesario hacerlo, sin ello se visualiza igual. Unicamente se hace porque de esta
259
                //forma el raster resultante mejora un poco en calidad en ciertos niveles de zoom ya que al aplicar transformaciones
260
                //sobre el Graphics parece que pierde algo de calidad.
261
                if(transf.getScaleX() > 0 && transf.getScaleY() < 0 && transf.getShearX() == 0 && transf.getShearY() == 0) {
262
                        Point2D lastGraphicOffset = new Point2D.Double(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY());
263
                        vp.mat.transform(lastGraphicOffset, lastGraphicOffset);
264
                        g.drawImage(geoImage, (int) Math.round(lastGraphicOffset.getX()), (int) Math.round(lastGraphicOffset.getY()), null);
265
                        return geoImage;
266
                }
267

    
268
                /*
269
                 * Tenemos una matriz con la transformaci?n de la coordenadas de la vista a coordenadas reales vp.mat, adem?s tenemos
270
                 * la transformaci?n de coordenadas reales a coordenadas pixel (transf). Con ambas podemos obtener una matriz de trasformacion
271
                 * entre coordenadas de la vista a coordenadas pixel (transf X vp.mat). As? obtenemos la transformaci?n entre coordenadas
272
                 * de la vista y coordenadas pixel del raster. El problemas es que cada zoom la escala de la petici?n del raster varia
273
                 * por lo que habr? que calcular una matriz con la escala (escale). escale X transf X vp.mat
274
                 */
275
                double sX = Math.abs(ulPxRequest.getX() - lrPxRequest.getX()) / widthImage;
276
                double sY = Math.abs(ulPxRequest.getY() - lrPxRequest.getY()) / heightImage;
277
                AffineTransform escale = new AffineTransform(sX, 0, 0, sY, 0, 0);
278

    
279
                try {
280
                        AffineTransform at = (AffineTransform)escale.clone();
281
                        at.preConcatenate(transf);
282
                        at.preConcatenate(vp.getMat());
283
                        g.transform(at);
284
                        Point2D.Double pt = null;
285
                        //El punto sobre el que rota la imagen depende del signo de los tama?os del pixel
286
                        if(transf.getScaleX() < 0 && transf.getScaleY() < 0)
287
                                pt = new Point2D.Double(adjustedRotedRequest.maxX(), adjustedRotedRequest.maxY());
288
                        else if(transf.getScaleX() > 0 && transf.getScaleY() > 0)
289
                                pt = new Point2D.Double(adjustedRotedRequest.minX(), adjustedRotedRequest.minY());
290
                        else if(transf.getScaleX() < 0 && transf.getScaleY() > 0)
291
                                pt = new Point2D.Double(adjustedRotedRequest.maxX(), adjustedRotedRequest.minY());
292
                        else
293
                                pt = new Point2D.Double(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY());
294
                        vp.getMat().transform(pt, pt);
295
                        at.inverseTransform(pt, pt);
296
                        g.drawImage(geoImage, (int) Math.round(pt.getX()), (int) Math.round(pt.getY()), null);
297
                        g.transform(at.createInverse());
298
                } catch (NoninvertibleTransformException e) {
299
                        e.printStackTrace();
300
                }
301
                return geoImage;
302
                // long t2 = new Date().getTime();
303
                // System.out.println("Renderizando Raster: " + ((t2 - t1) / 1000D) + ", secs.");
304
        }
305

    
306
        /**
307
         * Calculamos la petici?n en coordenadas del mundo real con la transformaci?n del raster. Esto
308
         * permite obtener las coordenadas de la petici?n con la rotaci?n, si la tiene.
309
         * @param vp
310
         * @param dataset
311
         * @return
312
         */
313
        private Extent request(ViewPortData vp, IRasterDataSource dataset) {
314
                if (dataset.isRotated()) {
315
                        //Obtenemos las cuatro esquinas de la selecci?n que hemos hecho en la vista
316
                        Point2D ul = new Point2D.Double(vp.getExtent().minX(), vp.getExtent().maxY());
317
                        Point2D ur = new Point2D.Double(vp.getExtent().maxX(), vp.getExtent().maxY());
318
                        Point2D ll = new Point2D.Double(vp.getExtent().minX(), vp.getExtent().minY());
319
                        Point2D lr = new Point2D.Double(vp.getExtent().maxX(), vp.getExtent().minY());
320

    
321
                        //Las pasamos a coordenadas pixel del raster
322
                        ul = dataset.worldToRaster(ul);
323
                        ur = dataset.worldToRaster(ur);
324
                        ll = dataset.worldToRaster(ll);
325
                        lr = dataset.worldToRaster(lr);
326

    
327
                        //Obtenemos los valores pixel m?ximos y m?nimos para X e Y
328
                        double pxMaxX = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
329
                        double pxMaxY = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
330
                        double pxMinX = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
331
                        double pxMinY = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
332

    
333
                        //Ajustamos las coordenadas pixel al ?rea m?xima del raster
334
                        pxMinX = Math.max(pxMinX, 0);
335
                        pxMinY = Math.max(pxMinY, 0);
336
                        pxMaxX = Math.min(pxMaxX, dataset.getWidth());
337
                        pxMaxY = Math.min(pxMaxY, dataset.getHeight());
338

    
339
                        //Petici?n en coordenadas pixel
340
                        ulPxRequest = new Point2D.Double(pxMinX, pxMinY);
341
                        lrPxRequest = new Point2D.Double(pxMaxX, pxMaxY);
342

    
343
                        //Calculamos el ancho y alto del buffer sobre el que se escribe la petici?n
344
                        widthImage = ((Math.abs(lrPxRequest.getX() - ulPxRequest.getX()) * vp.getWidth()) / Math.abs(ul.getX() - ur.getX()));
345
                        heightImage = ((Math.abs(lrPxRequest.getY() - ulPxRequest.getY()) * vp.getHeight()) / Math.abs(ur.getY() - lr.getY()));
346

    
347
                        //Convertimos la petici?n en coordenadas pixel a petici?n en coordenadas reales.
348
                        Point2D ulWC = dataset.rasterToWorld(ulPxRequest);
349
                        Point2D lrWC = dataset.rasterToWorld(lrPxRequest);
350

    
351
                        //Ajustamos la petici?n a los limites del raster, teniendo en cuenta la rotaci?n de este.
352
                        return new Extent(ulWC, lrWC);
353
                }
354
                Extent adjustedRotedExtent = RasterUtilities.calculateAdjustedView(vp.getExtent(), dataset.getAffineTransform(), new Dimension((int)dataset.getWidth(), (int)dataset.getHeight()));
355
                widthImage = (int)Math.round(Math.abs(adjustedRotedExtent.width() * vp.getMat().getScaleX()));
356
                heightImage = (int)Math.round(Math.abs(adjustedRotedExtent.height() * vp.getMat().getScaleY()));
357
                Point2D ul = new Point2D.Double(adjustedRotedExtent.getULX(), adjustedRotedExtent.getULY());
358
                Point2D lr = new Point2D.Double(adjustedRotedExtent.getLRX(), adjustedRotedExtent.getLRY());
359
                ul = dataset.worldToRaster(ul);
360
                lr = dataset.worldToRaster(lr);
361
                ulPxRequest = new Point2D.Double(ul.getX(), ul.getY());
362
                lrPxRequest = new Point2D.Double(lr.getX(), lr.getY());
363
                return adjustedRotedExtent;
364
        }
365

    
366
        /**
367
         * Obtiene el n?mero de bandas y el orden de renderizado. Cada posici?n del
368
         * vector es una banda del buffer y el contenido de esa posici?n es la banda
369
         * de la imagen que se dibujar? sobre ese buffer. A la hora de renderizar hay
370
         * que tener en cuenta que solo se renderizan las tres primeras bandas del
371
         * buffer por lo que solo se tienen en cuenta los tres primeros elementos. Por
372
         * ejemplo, el array {1, 0, 3} dibujar? sobre el Graphics las bandas 1,0 y 3
373
         * de un raster de al menos 4 bandas. La notaci?n con -1 en alguna posici?n
374
         * del vector solo tiene sentido en la visualizaci?n pero no se puede as?gnar
375
         * una banda del buffer a null. Algunos ejemplos:
376
         * <P>
377
         * <UL>
378
         * <LI> {-1, 0, -1} Dibuja la banda 0 del raster en la G de la visualizaci?n. Si
379
         * replicateBand es true R = G = B sino R = B = 0 </LI>
380
         * <LI> {1, 0, 3} La R = banda 1 del raster, G = 0 y B = 3 </LI>
381
         * <LI> {0} La R = banda 0 del raster. Si replicateBand es true R = G = B 
382
         * sino G = B = 0</LI>
383
         * </UL>
384
         * </P>
385
         *
386
         * @return bandas y su posici?n
387
         */
388
        public int[] getRenderBands() {
389
                return renderBands;
390
        }
391

    
392
        /**
393
                 * Asigna el n?mero de bandas y el orden de renderizado. Cada posici?n del vector es una banda
394
         * del buffer y el contenido de esa posici?n es la banda de la imagen que se dibujar?
395
         * sobre ese buffer. A la hora de renderizar hay que tener en cuenta que solo se renderizan las
396
         * tres primeras bandas del buffer por lo que solo se tienen en cuenta los tres primeros
397
         * elementos. Por ejemplo, el array {1, 0, 3} dibujar? sobre el Graphics las bandas 1,0 y 3 de un
398
         * raster que tiene al menos 4 bandas. La notaci?n con -1 en alguna posici?n del vector solo tiene sentido
399
         * en la visualizaci?n pero no se puede as?gnar una banda del buffer a null.
400
         * Algunos ejemplos:
401
         * <P>
402
         * {-1, 0, -1} Dibuja la banda 0 del raster en la G de la visualizaci?n.
403
         * Si replicateBand es true R = G = B sino R = B = 0
404
         * {1, 0, 3} La R = banda 1 del raster, G = 0 y B = 3
405
         * {0} La R = banda 0 del raster. Si replicateBand es true R = G = B sino G = B = 0
406
         * </P>
407
         *
408
         *
409
                 * @param renderBands: bandas y su posici?n
410
                 */
411
        public void setRenderBands(int[] renderBands) {
412
                this.renderBands = renderBands;
413
                if (filterList != null) {
414
                        for (int i = 0; i < filterList.lenght(); i++)
415
                                ((RasterFilter) filterList.get(i)).addParam("renderBands", renderBands);
416
                }
417
        }
418

    
419
        /**
420
         * Dado que la notaci?n de bandas para renderizado admite posiciones con -1 y la notaci?n del
421
         * buffer no ya que no tendria sentido. Esta funci?n adapta la primera notaci?n a la segunda
422
         * para realizar la petici?n setAreaOfInterest y cargar el buffer.
423
         * @param b Array que indica la posici?n de bandas para el renderizado
424
         * @return Array que indica la posici?n de bandas para la petici?n
425
         */
426
        public int[] formatArrayRenderBand(int[] b) {
427
                int cont = 0;
428
                for(int i = 0; i < b.length; i++)
429
                        if(b[i] >= 0)
430
                                cont ++;
431
                if(cont <= 0)
432
                        return null;
433
                int[] out = new int[cont];
434
                int pos = 0;
435
                for(int i = 0; i < cont; i++) {
436
                        while(b[pos] == -1)
437
                                pos ++;
438
                        out[i] = b[pos];
439
                        pos ++;
440
                }
441
                return out;
442
        }
443

    
444
        /**
445
         * Obtiene el ?ltimo objeto transparencia aplicado en la renderizaci?n
446
         * @return GridTransparency
447
         */
448
        public GridTransparency getLastTransparency() {
449
                return lastTransparency;
450
        }
451

    
452
        public void setLastTransparency(GridTransparency lastTransparency) {
453
                this.lastTransparency = lastTransparency;
454
                if (getFilterList() != null)
455
                        getFilterList().addEnvParam("Transparency", lastTransparency);
456
        }
457

    
458
        /**
459
         * Obtiene las lista de filtros aplicados en la renderizaci?n
460
         * @return RasterFilterList
461
         */
462
        public RasterFilterList getFilterList() {
463
                return filterList;
464
        }
465

    
466
        /**
467
         * Obtiene el ?ltimo buffer renderizado.
468
         * @return IBuffer
469
         */
470
        public IBuffer getLastRenderBuffer() {
471
                return this.lastRenderBuffer;
472
        }
473

    
474
        /**
475
         * Asigna el ?ltimo renderizado.
476
         * @param buf
477
         */
478
        public void setLastRenderBuffer(IBuffer buf) {
479
                this.lastRenderBuffer = buf;
480
        }
481

    
482
        /**
483
         * Asigna la lista de filtros que se usar? en el renderizado
484
         * @param RasterFilterList
485
         */
486
        public void setFilterList(RasterFilterList filterList) {
487
                this.filterList = filterList;
488
        }
489

    
490
        /**
491
         * Informa de si el raster tiene tabla de color asociada o no.
492
         * @return true si tiene tabla de color y false si no la tiene.
493
         */
494
        public boolean existColorTable() {
495
                        return (filterList.getFilterByBaseClass(ColorTableFilter.class) != null);
496
        }
497

    
498
        /**
499
         * Obtiene el grid asociado al render
500
         * @return
501
         */
502
        public Grid getGrid() {
503
                return grid;
504
        }
505

    
506
        /**
507
         * Asigna la factoria de buffer del renderizador
508
         * @param bf
509
         */
510
        public void setBufferFactory(BufferFactory bf) {
511
                this.bufferFactory = bf;
512
        }
513
}