Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / grid / render / DefaultRender.java @ 162

History | View | Annotate | Download (24.2 KB)

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.impl.grid.render;
23

    
24
import java.awt.Dimension;
25
import java.awt.Graphics2D;
26
import java.awt.Image;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.NoninvertibleTransformException;
29
import java.awt.geom.Point2D;
30
import java.util.ArrayList;
31

    
32
import org.gvsig.fmap.dal.coverage.RasterLocator;
33
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
34
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
35
import org.gvsig.fmap.dal.coverage.datastruct.ViewPortData;
36
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
37
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
38
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
39
import org.gvsig.fmap.dal.coverage.grid.FilterListChangeEvent;
40
import org.gvsig.fmap.dal.coverage.grid.FilterListChangeListener;
41
import org.gvsig.fmap.dal.coverage.grid.Grid;
42
import org.gvsig.fmap.dal.coverage.grid.GridTransparency;
43
import org.gvsig.fmap.dal.coverage.grid.RasterFilter;
44
import org.gvsig.fmap.dal.coverage.grid.RasterFilterList;
45
import org.gvsig.fmap.dal.coverage.grid.render.Render;
46
import org.gvsig.fmap.dal.coverage.grid.render.VisualPropertyEvent;
47
import org.gvsig.fmap.dal.coverage.grid.render.VisualPropertyListener;
48
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
49
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
50
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
51
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
52
import org.gvsig.fmap.dal.coverage.util.PropertyEvent;
53
import org.gvsig.fmap.dal.coverage.util.PropertyListener;
54
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
55
import org.gvsig.raster.impl.DefaultRasterManager;
56
import org.gvsig.raster.impl.datastruct.DefaultViewPortData;
57
import org.gvsig.raster.impl.datastruct.ExtentImpl;
58
import org.gvsig.raster.impl.grid.GridImpl;
59
import org.gvsig.raster.impl.grid.GridTransparencyImpl;
60
import org.gvsig.raster.impl.grid.filter.DefaultRasterFilterList;
61
import org.gvsig.raster.impl.grid.filter.band.ColorTableFilter;
62
import org.gvsig.raster.impl.store.DefaultMultiRasterStore;
63
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
64
import org.gvsig.tools.ToolsLocator;
65
import org.gvsig.tools.dynobject.DynStruct;
66
import org.gvsig.tools.persistence.PersistenceManager;
67
import org.gvsig.tools.persistence.Persistent;
68
import org.gvsig.tools.persistence.PersistentState;
69
import org.gvsig.tools.persistence.exception.PersistenceException;
70
/**
71
 * Esta clase se encarga de la gesti?n del dibujado de datos le?dos desde la capa
72
 * "dataaccess" sobre objetos java. Para ello necesita una fuente de datos que tipicamente
73
 * es un buffer (RasterBuffer) y un objeto que realice la funci?n de escritura de datos a
74
 * partir de un estado inicial.
75
 * Esta capa del renderizado gestiona Extents, rotaciones, tama?os de vista pero la escritura
76
 * de datos desde el buffer al objeto image es llevada a cabo por ImageDrawer.
77
 *
78
 * Par?metros de control de la visualizaci?n:
79
 * <UL>
80
 * <LI>renderBands: Orden de visualizado de las bands.</LI>
81
 * <LI>replicateBands: Para visualizaci?n de raster de una banda. Dice si se replica sobre las otras dos bandas
82
 * de visualizaci?n o se ponen a 0.</LI>
83
 * <LI>enhanced: aplicaci?n de filtro de realce</LI>
84
 * <LI>removeEnds: Eliminar extremos en el filtro de realce. Uso del segundo m?ximo y m?nimo</LI>
85
 * <LI>tailTrim: Aplicacion de recorte de colas en el realce. Es un valor decimal que representa el porcentaje del recorte entre 100.
86
 * Es decir, 0.1 significa que el recorte es de un 10%</LI>
87
 * </UL>
88
 *
89
 * @author Nacho Brodin (nachobrodin@gmail.com)
90
 */
91
public class DefaultRender implements Render, PropertyListener, FilterListChangeListener, Persistent {
92

    
93
        /**
94
         * Grid para la gesti?n del buffer
95
         */
96
        private Grid             grid                     = null;
97
        /**
98
         * Fuente de datos para el renderizado
99
         */
100
        private RasterDataStore dataStore                 = null;
101
        /**
102
         * N?mero de bandas a renderizar y en el orden que se har?. Esto es asignado
103
         * por el usuario de la renderizaci?n.
104
         */
105
        private int[]            renderBands              = { 0, 1, 2 };
106
        /**
107
         * Tiene el comportamiento cuando se tiene un raster con una. Dice si en las
108
         * otras bandas a renderizar se replica la banda existente o se ponen a 0.
109
         */
110
        private boolean          replicateBand            = false;
111

    
112
        private ImageDrawer      drawer                   = null;
113
        /**
114
         * Ultima transparencia aplicada en la visualizaci?n que es obtenida desde el
115
         * grid
116
         */
117
        private GridTransparency lastTransparency         = null;
118
        /**
119
         * Lista de filtros aplicada en la renderizaci?n
120
         */
121
        private RasterFilterList filterList               = null;
122

    
123
        private Buffer           lastRenderBuffer         = null;
124

    
125
        /**
126
         * Ancho y alto del objeto Image en una petici?n de dibujado a un raster
127
         * raster
128
         */
129
        private double           widthImage, heightImage;
130

    
131
        private Point2D          ulPxRequest, lrPxRequest;
132

    
133
        /**
134
         * Array de listeners que ser?n informados cuando cambia una propiedad en la visualizaci?n
135
         */
136
        private ArrayList<VisualPropertyListener>        
137
                                 visualPropertyListener   = new ArrayList<VisualPropertyListener>();
138
        private RasterUtils      util                     = RasterLocator.getManager().getRasterUtils();
139
        
140
        /**
141
         * Constructor
142
         */
143
        public DefaultRender() {
144
                init();
145
        }
146

    
147
        /**
148
         * Constructor
149
         * @param grid
150
         */
151
        public DefaultRender(Grid grid) {
152
                this.grid = grid;
153
                init();
154
        }
155

    
156
        /**
157
         * Constructor
158
         * @param grid
159
         */
160
        public DefaultRender(RasterDataStore ds) {
161
                this.dataStore = ds;
162
                init();
163
        }
164

    
165
        private void init() {
166
                drawer = new ImageDrawer(this);
167

    
168
                if (dataStore == null) {
169
                        setRenderBands(new int[] { 0, 1, 2 });
170
                        return;
171
                }
172

    
173
                //Bandas que se dibujan por defecto si la interpretaci?n de color no tiene valores
174
                switch (dataStore.getBandCount()) {
175
                        case 1:
176
                                setRenderBands(new int[] { 0, 0, 0 });
177
                                break;
178
                        case 2:
179
                                setRenderBands(new int[] { 0, 1, 1 });
180
                                break;
181
                        default:
182
                                setRenderBands(new int[] { 0, 1, 2 });
183
                                break;
184
                }
185

    
186
                //---------------------------------------------------
187
                //INICIALIZACI?N DE LA INTERPRETACI?N DE COLOR
188

    
189
                //Inicializaci?n de la asignaci?n de bandas en el renderizado
190
                //Leemos el objeto metadata para obtener la interpretaci?n de color asociada al raster
191
                if ((dataStore instanceof DefaultMultiRasterStore && ((DefaultMultiRasterStore)dataStore).getDataStoreCount() == 1)) { 
192
                                
193
                        ColorInterpretation colorInterpr = dataStore.getColorInterpretation();
194
                        if (colorInterpr != null)
195
                                if (colorInterpr.getBand(DataStoreColorInterpretation.PAL_BAND) == -1) {
196
                                        if (colorInterpr.isUndefined())
197
                                                return;
198
                                        int[] result = new int[] { -1, -1, -1 };
199
                                        int gray = colorInterpr.getBand(DataStoreColorInterpretation.GRAY_BAND);
200
                                        if (gray != -1)
201
                                                result[0] = result[1] = result[2] = gray;
202
                                        else {
203
                                                int r = colorInterpr.getBand(DataStoreColorInterpretation.RED_BAND);
204
                                                if (r != -1)
205
                                                        result[0] = r;
206
                                                int g = colorInterpr.getBand(DataStoreColorInterpretation.GREEN_BAND);
207
                                                if (g != -1)
208
                                                        result[1] = g;
209
                                                int b = colorInterpr.getBand(DataStoreColorInterpretation.BLUE_BAND);
210
                                                if (b != -1)
211
                                                        result[2] = b;
212
                                        }
213
                                        setRenderBands(result);
214
                                }
215
                }
216
        }
217

    
218
        /**
219
         * Asigna un listener a la lista que ser? informado cuando cambie una
220
         * propiedad visual en la renderizaci?n.
221
         * @param listener VisualPropertyListener
222
         */
223
        public void addVisualPropertyListener(VisualPropertyListener listener) {
224
                visualPropertyListener.add(listener);
225
        }
226

    
227
        /**
228
         * M?todo llamado cuando hay un cambio en una propiedad de visualizaci?n
229
         */
230
        private void callVisualPropertyChanged(Object obj) {
231
                for (int i = 0; i < visualPropertyListener.size(); i++) {
232
                        VisualPropertyEvent ev = new VisualPropertyEvent(obj);
233
                        ((VisualPropertyListener)visualPropertyListener.get(i)).visualPropertyValueChanged(ev);
234
                }
235
        }
236

    
237
        /*
238
         * (non-Javadoc)
239
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#draw(java.awt.Graphics2D, org.cresques.geo.ViewPortData)
240
         */
241
        public synchronized Image draw(Graphics2D g, ViewPortData vp)
242
                throws RasterDriverException, InvalidSetViewException, ProcessInterruptedException {
243
                Image geoImage = null;
244
                //RasterDataSet dataset = dataStore.getDataset();
245
                AffineTransform transf = dataStore.getAffineTransform();
246

    
247
                if(util.isOutside(vp.getExtent(), dataStore.getExtent()))
248
                        return null;
249

    
250
                Extent adjustedRotedRequest = request(vp, dataStore);
251

    
252
                if ((widthImage <= 0) || (heightImage <= 0))
253
                        return null;
254

    
255
                double[] step = null;
256
                Buffer buf = null;
257
                
258
                if (dataStore != null) {
259
                        if (lastTransparency == null) {
260
                                lastTransparency = new GridTransparencyImpl(dataStore.getTransparency());
261
                                lastTransparency.addPropertyListener(this);
262
                        }
263
                        // Asignamos la banda de transparencia si existe esta
264
                        RasterQuery query = DefaultRasterManager.getInstance().createQuery();
265
                        if (dataStore.getTransparency().getAlphaBandNumber() != -1) {
266
                                query.setSupersamplingLoadingBuffer(false); // Desactivamos el supersampleo en la carga del buffer.
267
                                query.setDrawableBands(new int[] { lastTransparency.getAlphaBandNumber(), -1, -1 });
268
                                query.setAreaOfInterest(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY(), adjustedRotedRequest.getLRX(), adjustedRotedRequest.getLRY(), (int)Math.round(widthImage), (int)Math.round(heightImage));
269
                                query.setSupersamplingLoadingBuffer(true);
270
                                lastTransparency.setAlphaBand(dataStore.query(query));
271
                        }
272
                        query.setSupersamplingLoadingBuffer(false); // Desactivamos el supersampleo en la carga del buffer.
273
                        // En el renderizado ser? ImageDrawer el que se encargue de esta funci?n
274
                        query.setDrawableBands(getRenderBands());
275
                        query.setAreaOfInterest(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY(), adjustedRotedRequest.getLRX(), adjustedRotedRequest.getLRY(), (int)Math.round(widthImage), (int)Math.round(heightImage));
276
                        buf = dataStore.query(query);
277
                        step = dataStore.getStep();
278
                        query.setSupersamplingLoadingBuffer(true);
279

    
280
                        //Asignamos los datos al objeto transparencia antes de aplicar la pila de filtros para que el valor NoData sea efectivo
281
                        if (dataStore.getTransparency().isNoDataActive())
282
                                lastTransparency.setDataBuffer(buf);
283
                        else
284
                                lastTransparency.setDataBuffer(null);
285
                        lastTransparency.activeTransparency();
286

    
287
                } else
288
                        return null;
289

    
290
                //Aplicamos los filtros
291
                grid = new GridImpl(buf, dataStore, true);
292
                if(filterList != null) {
293
                        filterList.addEnvParam("Transparency", lastTransparency);
294
                        grid.setFilterList(filterList);
295
                        grid.applyFilters();
296
                }
297
                
298
                //Si la lista de filtros genera bandas de transparencia se mezclan con la actual
299
                if(grid.getFilterList().getAlphaBand() != null) {
300
                        Buffer t = grid.getFilterList().getAlphaBand();
301
                        if(lastTransparency.getAlphaBand() != null)
302
                                t = RasterLocator.getManager().getColorConversion().mergeTransparencyBuffers(t, lastTransparency.getAlphaBand());
303
                        lastTransparency.setAlphaBand(t);
304
                        lastTransparency.activeTransparency();
305
                }
306

    
307
                //Buffer filtrado para renderizar
308
                lastRenderBuffer = grid.getRasterBuf();
309
                drawer.setBuffer(lastRenderBuffer); // Buffer de datos a renderizar
310
                drawer.setStep(step); // Desplazamiento para supersampleo
311
                drawer.setBufferSize((int)Math.round(widthImage), (int)Math.round(heightImage)); // Ancho y alto del buffer
312
                geoImage = drawer.drawBufferOverImageObject(replicateBand, getRenderBands()); // Acci?n de renderizado
313

    
314
                // Borramos el buffer de transparencia para que siempre se tenga que regenerar.
315
                lastTransparency.setAlphaBand(null);
316

    
317
                //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
318
                //transformaci?n. Esto no es necesario hacerlo, sin ello se visualiza igual. Unicamente se hace porque de esta
319
                //forma el raster resultante mejora un poco en calidad en ciertos niveles de zoom ya que al aplicar transformaciones
320
                //sobre el Graphics parece que pierde algo de calidad.
321
                if(transf.getScaleX() > 0 && transf.getScaleY() < 0 && transf.getShearX() == 0 && transf.getShearY() == 0) {
322
                        Point2D lastGraphicOffset = new Point2D.Double(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY());
323
                        ((DefaultViewPortData)vp).mat.transform(lastGraphicOffset, lastGraphicOffset);
324
                        g.drawImage(geoImage, (int) Math.round(lastGraphicOffset.getX()), (int) Math.round(lastGraphicOffset.getY()), null);
325
                        return geoImage;
326
                }
327

    
328
                /*
329
                 * Tenemos una matriz con la transformaci?n de la coordenadas de la vista a coordenadas reales vp.mat, adem?s tenemos
330
                 * la transformaci?n de coordenadas reales a coordenadas pixel (transf). Con ambas podemos obtener una matriz de trasformacion
331
                 * entre coordenadas de la vista a coordenadas pixel (transf X vp.mat). As? obtenemos la transformaci?n entre coordenadas
332
                 * de la vista y coordenadas pixel del raster. El problemas es que cada zoom la escala de la petici?n del raster varia
333
                 * por lo que habr? que calcular una matriz con la escala (escale). escale X transf X vp.mat
334
                 */
335
                double sX = Math.abs(ulPxRequest.getX() - lrPxRequest.getX()) / widthImage;
336
                double sY = Math.abs(ulPxRequest.getY() - lrPxRequest.getY()) / heightImage;
337
                AffineTransform escale = new AffineTransform(sX, 0, 0, sY, 0, 0);
338

    
339
                try {
340
                        AffineTransform at = (AffineTransform)escale.clone();
341
                        at.preConcatenate(transf);
342
                        at.preConcatenate(vp.getMat());
343
                        g.transform(at);
344
                        Point2D.Double pt = null;
345
                        //El punto sobre el que rota la imagen depende del signo de los tama?os del pixel
346
                        if(transf.getScaleX() < 0 && transf.getScaleY() < 0)
347
                                pt = new Point2D.Double(adjustedRotedRequest.maxX(), adjustedRotedRequest.maxY());
348
                        else if(transf.getScaleX() > 0 && transf.getScaleY() > 0)
349
                                pt = new Point2D.Double(adjustedRotedRequest.minX(), adjustedRotedRequest.minY());
350
                        else if(transf.getScaleX() < 0 && transf.getScaleY() > 0)
351
                                pt = new Point2D.Double(adjustedRotedRequest.maxX(), adjustedRotedRequest.minY());
352
                        else
353
                                pt = new Point2D.Double(adjustedRotedRequest.getULX(), adjustedRotedRequest.getULY());
354
                        vp.getMat().transform(pt, pt);
355
                        at.inverseTransform(pt, pt);
356
                        g.drawImage(geoImage, (int) Math.round(pt.getX()), (int) Math.round(pt.getY()), null);
357
                        g.transform(at.createInverse());
358
                } catch (NoninvertibleTransformException e) {
359
                        e.printStackTrace();
360
                }
361
                return geoImage;
362
                // long t2 = new Date().getTime();
363
                // System.out.println("Renderizando Raster: " + ((t2 - t1) / 1000D) + ", secs.");
364
        }
365

    
366
        /**
367
         * Calculamos la petici?n en coordenadas del mundo real con la transformaci?n del raster. Esto
368
         * permite obtener las coordenadas de la petici?n con la rotaci?n, si la tiene.
369
         * @param vp
370
         * @param ldatastore
371
         * @return
372
         */
373
        private Extent request(ViewPortData vp, RasterDataStore ldatastore) {
374
                if (ldatastore.isRotated()) {
375
                        //Obtenemos las cuatro esquinas de la selecci?n que hemos hecho en la vista
376
                        Point2D ul = new Point2D.Double(vp.getExtent().minX(), vp.getExtent().maxY());
377
                        Point2D ur = new Point2D.Double(vp.getExtent().maxX(), vp.getExtent().maxY());
378
                        Point2D ll = new Point2D.Double(vp.getExtent().minX(), vp.getExtent().minY());
379
                        Point2D lr = new Point2D.Double(vp.getExtent().maxX(), vp.getExtent().minY());
380

    
381
                        //Las pasamos a coordenadas pixel del raster
382
                        ul = ldatastore.worldToRaster(ul);
383
                        ur = ldatastore.worldToRaster(ur);
384
                        ll = ldatastore.worldToRaster(ll);
385
                        lr = ldatastore.worldToRaster(lr);
386

    
387
                        //Obtenemos los valores pixel m?ximos y m?nimos para X e Y
388
                        double pxMaxX = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
389
                        double pxMaxY = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
390
                        double pxMinX = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
391
                        double pxMinY = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
392

    
393
                        //Ajustamos las coordenadas pixel al ?rea m?xima del raster
394
                        pxMinX = Math.max(pxMinX, 0);
395
                        pxMinY = Math.max(pxMinY, 0);
396
                        pxMaxX = Math.min(pxMaxX, ldatastore.getWidth());
397
                        pxMaxY = Math.min(pxMaxY, ldatastore.getHeight());
398

    
399
                        //Petici?n en coordenadas pixel
400
                        ulPxRequest = new Point2D.Double(pxMinX, pxMinY);
401
                        lrPxRequest = new Point2D.Double(pxMaxX, pxMaxY);
402

    
403
                        //Calculamos el ancho y alto del buffer sobre el que se escribe la petici?n
404
                        widthImage = ((Math.abs(lrPxRequest.getX() - ulPxRequest.getX()) * vp
405
                                        .getWidth()) / Math.abs(pxMaxX - pxMinX));
406
                        heightImage = ((Math.abs(lrPxRequest.getY() - ulPxRequest.getY()) * vp
407
                                        .getHeight()) / Math.abs(pxMaxY - pxMinY));
408

    
409
                        //Convertimos la petici?n en coordenadas pixel a petici?n en coordenadas reales.
410
                        Point2D ulWC = ldatastore.rasterToWorld(ulPxRequest);
411
                        Point2D lrWC = ldatastore.rasterToWorld(lrPxRequest);
412

    
413
                        //Ajustamos la petici?n a los limites del raster, teniendo en cuenta la rotaci?n de este.
414
                        return new ExtentImpl(ulWC, lrWC);
415
                }
416
                Extent adjustedRotedExtent = util.calculateAdjustedView(vp.getExtent(), ldatastore.getAffineTransform(), new Dimension((int)ldatastore.getWidth(), (int)ldatastore.getHeight()));
417
                widthImage = (int)Math.round(Math.abs(adjustedRotedExtent.width() * vp.getMat().getScaleX()));
418
                heightImage = (int)Math.round(Math.abs(adjustedRotedExtent.height() * vp.getMat().getScaleY()));
419
                Point2D ul = new Point2D.Double(adjustedRotedExtent.getULX(), adjustedRotedExtent.getULY());
420
                Point2D lr = new Point2D.Double(adjustedRotedExtent.getLRX(), adjustedRotedExtent.getLRY());
421
                ul = ldatastore.worldToRaster(ul);
422
                lr = ldatastore.worldToRaster(lr);
423
                ulPxRequest = new Point2D.Double(ul.getX(), ul.getY());
424
                lrPxRequest = new Point2D.Double(lr.getX(), lr.getY());
425
                return adjustedRotedExtent;
426
        }
427

    
428
        /*
429
         * (non-Javadoc)
430
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#getRenderBands()
431
         */
432
        public int[] getRenderBands() {
433
                return renderBands;
434
        }
435

    
436
        /**
437
                 * Asigna el n?mero de bandas y el orden de renderizado. Cada posici?n del vector es una banda
438
         * del buffer y el contenido de esa posici?n es la banda de la imagen que se dibujar?
439
         * sobre ese buffer. A la hora de renderizar hay que tener en cuenta que solo se renderizan las
440
         * tres primeras bandas del buffer por lo que solo se tienen en cuenta los tres primeros
441
         * elementos. Por ejemplo, el array {1, 0, 3} dibujar? sobre el Graphics las bandas 1,0 y 3 de un
442
         * raster que tiene al menos 4 bandas. La notaci?n con -1 en alguna posici?n del vector solo tiene sentido
443
         * en la visualizaci?n pero no se puede as?gnar una banda del buffer a null.
444
         * Algunos ejemplos:
445
         * <P>
446
         * {-1, 0, -1} Dibuja la banda 0 del raster en la G de la visualizaci?n.
447
         * Si replicateBand es true R = G = B sino R = B = 0
448
         * {1, 0, 3} La R = banda 1 del raster, G = 0 y B = 3
449
         * {0} La R = banda 0 del raster. Si replicateBand es true R = G = B sino G = B = 0
450
         * </P>
451
         *
452
         *
453
                 * @param renderBands: bandas y su posici?n
454
                 */
455
        public void setRenderBands(int[] renderBands) {
456
                if(        renderBands[0] != this.renderBands[0] ||
457
                        renderBands[1] != this.renderBands[1] ||
458
                        renderBands[2] != this.renderBands[2])
459
                        callVisualPropertyChanged(renderBands);
460
                this.renderBands = renderBands;
461
                if (filterList != null)
462
                        for (int i = 0; i < filterList.lenght(); i++)
463
                                (filterList.get(i)).addParam("renderBands", renderBands);
464
        }
465

    
466
        /**
467
         * Dado que la notaci?n de bandas para renderizado admite posiciones con -1 y la notaci?n del
468
         * buffer no ya que no tendria sentido. Esta funci?n adapta la primera notaci?n a la segunda
469
         * para realizar la petici?n setAreaOfInterest y cargar el buffer.
470
         * @param b Array que indica la posici?n de bandas para el renderizado
471
         * @return Array que indica la posici?n de bandas para la petici?n
472
         */
473
        public int[] formatArrayRenderBand(int[] b) {
474
                int cont = 0;
475
                for(int i = 0; i < b.length; i++)
476
                        if(b[i] >= 0)
477
                                cont ++;
478
                if(cont <= 0)
479
                        return null;
480
                int[] out = new int[cont];
481
                int pos = 0;
482
                for(int i = 0; i < cont; i++) {
483
                        while(b[pos] == -1)
484
                                pos ++;
485
                        out[i] = b[pos];
486
                        pos ++;
487
                }
488
                return out;
489
        }
490

    
491
        /*
492
         * (non-Javadoc)
493
         * @see org.gvsig.fmap.dal.coverage.grid.Render#getLastTransparency()
494
         */
495
        public GridTransparency getLastTransparency() {
496
                return lastTransparency;
497
        }
498

    
499
        /*
500
         * (non-Javadoc)
501
         * @see org.gvsig.fmap.dal.coverage.grid.Render#setLastTransparency(org.gvsig.fmap.dal.coverage.grid.GridTransparency)
502
         */
503
        public void setLastTransparency(GridTransparency lastTransparency) {
504
                if(lastTransparency instanceof GridTransparencyImpl) {
505
                        this.lastTransparency = (GridTransparencyImpl)lastTransparency;
506
                        this.lastTransparency.addPropertyListener(this);
507
                        if (getFilterList() != null)
508
                                getFilterList().addEnvParam("Transparency", lastTransparency);
509
                }
510
        }
511

    
512
        /*
513
         * (non-Javadoc)
514
         * @see org.gvsig.fmap.dal.coverage.grid.Render#getFilterList()
515
         */
516
        public RasterFilterList getFilterList() {
517
                return filterList;
518
        }
519

    
520
        /*
521
         * (non-Javadoc)
522
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#getLastRenderBuffer()
523
         */
524
        public Buffer getLastRenderBuffer() {
525
                return this.lastRenderBuffer;
526
        }
527

    
528
        /*
529
         * (non-Javadoc)
530
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#setLastRenderBuffer(org.gvsig.fmap.dal.coverage.dataset.Buffer)
531
         */
532
        public void setLastRenderBuffer(Buffer buf) {
533
                this.lastRenderBuffer = buf;
534
        }
535

    
536
        /*
537
         * (non-Javadoc)
538
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#setFilterList(org.gvsig.fmap.dal.coverage.grid.RasterFilterList)
539
         */
540
        public void setFilterList(RasterFilterList filterList) {
541
                this.filterList = filterList;
542
                this.filterList.addFilterListListener(this);
543
        }
544

    
545
        /*
546
         * (non-Javadoc)
547
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#existColorTable()
548
         */
549
        public boolean existColorTable() {
550
                        return (filterList.getFilterByBaseClass(ColorTableFilter.class) != null);
551
        }
552
        
553
        /*
554
         * (non-Javadoc)
555
         * @see org.gvsig.fmap.dal.coverage.grid.render.Render#getColorTable()
556
         */
557
        public ColorTable getColorTable() {
558
                if(existColorTable()) {
559
                        RasterFilter f = filterList.getFilterByBaseClass(ColorTableFilter.class);
560
                        return ((ColorTableFilter)f).getColorTable();
561
                }
562
                return null;
563
        }
564

    
565
        /**
566
         * Obtiene el grid asociado al render
567
         * @return
568
         */
569
        public Grid getGrid() {
570
                return grid;
571
        }
572

    
573
        /**
574
         * Asigna la factoria de buffer del renderizador
575
         * @param bf
576
         */
577
        public void setDataSource(RasterDataStore ds) {
578
                this.dataStore = ds;
579
        }
580

    
581
        /**
582
         * Evento activado cuando cambia una propiedad de transparencia.
583
         */
584
        public void actionValueChanged(PropertyEvent e) {
585
                callVisualPropertyChanged(new VisualPropertyEvent(e.getSource()));
586
        }
587

    
588
        /**
589
         * Evento activado cuando cambia la lista de filtros.
590
         */
591
        public void filterListChanged(FilterListChangeEvent e) {
592
                callVisualPropertyChanged(new VisualPropertyEvent(e.getSource()));
593
        }
594

    
595
        /**
596
         * Sets buffers to null
597
         */
598
        public void free() {
599
                if (lastTransparency != null)
600
                        lastTransparency.free();
601
                if (grid != null && grid instanceof GridImpl)
602
                        ((GridImpl)grid).free();
603
                if (getFilterList() != null && getFilterList() instanceof DefaultRasterFilterList)
604
                        ((DefaultRasterFilterList)getFilterList()).free();
605
                grid = null;
606
                dataStore = null;
607
                if (lastRenderBuffer != null)
608
                        lastRenderBuffer.free();
609
                lastRenderBuffer = null;
610
        }
611

    
612
        public void loadFromState(PersistentState state)
613
                        throws PersistenceException {
614
                lastTransparency = (GridTransparencyImpl)state.get("lastTransparency");                
615
        }
616

    
617
        public void saveToState(PersistentState state) throws PersistenceException {
618
                state.set("lastTransparency", lastTransparency);        
619
        }
620
        
621
        public static void registerPersistent() {
622
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
623
                DynStruct definition = manager.addDefinition(
624
                                DefaultRender.class,
625
                                "RasterRendering",
626
                                "RasterRendering Persistent definition",
627
                                null, 
628
                                null
629
                );
630
                definition.addDynField("lastTransparency");
631
        }
632

    
633
}