Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extRasterTools-SE / src / org / gvsig / fmap / raster / layers / RasterDrawStrategy.java @ 28995

History | View | Annotate | Download (8.89 KB)

1 16998 nbrodin
/* 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.fmap.raster.layers;
20
21
import java.util.ArrayList;
22
import java.util.HashMap;
23
24 26368 nbrodin
import org.gvsig.fmap.mapcontext.MapContext;
25
import org.gvsig.fmap.mapcontext.layers.FLayer;
26
import org.gvsig.fmap.mapcontext.layers.FLayers;
27 16998 nbrodin
import org.gvsig.raster.datastruct.Extent;
28 24387 nbrodin
import org.gvsig.raster.grid.filter.RasterFilter;
29
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
30 16998 nbrodin
import org.gvsig.raster.util.RasterUtilities;
31
32
/**
33
 * Aplica estrategias de dibujado para las capas raster. Hace que las
34
 * capas que est?n ocultas por otras no sean dibujadas. Esta estrategia tiene que ser
35
 * aplicada a capas raster de FMap por falta de eficiencia en el dibujado. Esta clase
36
 * es totalmente dependiente de FMap y puede ser eliminada en caso de que este no exita.
37
 * 28/11/2007
38
 * @author Nacho Brodin nachobrodin@gmail.com
39
 */
40
public class RasterDrawStrategy {
41
42 21626 nbrodin
        /**
43
         * Cada mapContext existente lleva asociadad una estrategia de dibujado
44
         */
45
        public static HashMap        mapContextStrategy    = new HashMap();
46
47
        private MapContext           mapContext            = null;
48
        private FLyrRasterSE         lyrRaster             = null;
49 16998 nbrodin
50
        /**
51 21626 nbrodin
         * Estructura de datos para almacenar la asociaci?n entre el extent de una capa
52
         * y su informaci?n de transparencia. Esta es necesaria para la comprobaci?n de si la
53
         * capa con la que se est? intersectando tiene transparencia o no la tiene. Con esto
54
         * se puede decidir si dibujar la capa actual o no.
55
         * 16/06/2008
56
         * @author Nacho Brodin nachobrodin@gmail.com
57
         */
58
        public class LayerIntersection {
59
                public Extent  extent          = null;
60
                public boolean hasTransparency = false;
61
                /**
62
                 * Constructor. Asigna el Extent y la informaci?n de transparencia
63
                 * @param ext Extent
64
                 * @param transp Transparencia
65
                 */
66
                public LayerIntersection(Extent ext, boolean transp) {
67
                        this.extent = ext;
68
                        this.hasTransparency = transp;
69
                }
70
        }
71
        /**
72 16998 nbrodin
         * Al constructor le pasamos el contexto de dibujado para la toma de decisi?n.
73
         * @param mapContext Context
74
         * @throws ExpansionFileReadException
75
         * @throws ReadDriverException
76
         */
77 26368 nbrodin
        public RasterDrawStrategy(MapContext mapContext, FLyrRasterSE lyrRaster) {
78 16998 nbrodin
                this.mapContext = mapContext;
79
                this.lyrRaster = lyrRaster;
80
        }
81
82
        /**
83
         * <P>
84
         * Estrategia de dibujado para las capas raster que hace que si
85
         * una capa est? oculta completamente por otra que no tiene transparencias entonces
86
         * esta no ser? dibujada.
87
         * </P>
88
         * <P>
89
         * La estrategia la calcula solo la primera capa raster que aparezca. El resto
90
         * de las capas la preguntaran a esta.
91
         * </P>
92
         * <P>
93
         * <code>Estrategia:</code>
94 21626 nbrodin
         * Analizamos la lista de capas desde la primera que se dibuja en el TOC hasta la ?ltima
95
         * <UL>
96
         * <LI>Si la capa tiene rotaci?n se dibuja siempre.</LI>
97
         * <LI>Si la capa no est? activa en el TOC no se dibuja nunca</LI>
98
         * <LI>Si la capa no es transparente y no hay extents en la lista se dibuja y se a?ade el extent a la lista</LI>
99
         * <LI>Si el extent de la capa intersecta con uno de la lista</LI>
100
         * </UL>
101 16998 nbrodin
         * Comprobamos si est? detr?s de un extent de la lista. Si es as? no se dibuja
102
         * Si no est? est? detr?s de un extent comprobamos si tiene transparencias
103
         * Si no tiene transparencias a?adimos el extent a la lista
104
         * </P>
105
         * @param lyrs
106
         * @throws ReadDriverException
107
         * @throws ExpansionFileReadException
108
         */
109 26368 nbrodin
        public void stackStrategy() {
110 21626 nbrodin
                if(mapContext == null || lyrRaster == null)
111 17177 nbrodin
                        return;
112 22019 nbrodin
113
                ArrayList listLayers = new ArrayList();
114 16998 nbrodin
                FLayers lyrs = mapContext.getLayers();
115 22019 nbrodin
                listLayers = getLayerList(lyrs, listLayers);
116
117 16998 nbrodin
                ArrayList extentList = new ArrayList();
118
119
                //Solo la primera capa calcula la estrategia. Las dem?s se la preguntan a esta.
120 21626 nbrodin
121
                //Calculamos cual es la primera capa raster de FLayers y contamos cuantas capas raster hay
122
                int posFirstRasterLayer = 0;
123
                int nRasterLayers = 0;
124
                boolean firstTime = true;
125 22019 nbrodin
                for (int i = 0; i < listLayers.size(); i++) {
126
                        FLayer lyr = (FLayer) listLayers.get(i);
127 21626 nbrodin
                        if(firstTime && lyr instanceof FLyrRasterSE && lyr.isVisible()) {
128
                                posFirstRasterLayer = i;
129
                                firstTime = false;
130 16998 nbrodin
                        }
131 21626 nbrodin
                        if(lyr instanceof FLyrRasterSE)
132
                                nRasterLayers ++;
133
                }
134 16998 nbrodin
135 21626 nbrodin
                //Si hay solo una capa raster no se calcula ninguna estrategia
136 21640 nbrodin
                if(nRasterLayers == 1) {
137
                        mapContextStrategy.put(mapContext, null);
138 21626 nbrodin
                        return;
139 21640 nbrodin
                }
140 21626 nbrodin
141
                //Si no es la primera capa se obtiene la estrategia que calcul? la primera capa
142 22019 nbrodin
                if(lyrRaster != listLayers.get(posFirstRasterLayer)) {
143
                        if(!(listLayers.get(posFirstRasterLayer) instanceof FLyrRasterSE))
144
                                return;
145
                        mapContextStrategy.put(mapContext, ((FLyrRasterSE)listLayers.get(posFirstRasterLayer)).getRasterStrategy());
146 21626 nbrodin
                        return;
147
                }
148
149
                HashMap layersToPaint = new HashMap();
150
151
                //Calculo de estrategia. Solo llega aqu? la primera capa.
152
                //La lista de capas en FLayers est? en orden inverso a lo que aparece en el TOC, es decir, la ?ltima capa
153
                //del TOC es la primera de la lista de FLayers y la primera del TOC es la ?ltima de la lista.
154 22019 nbrodin
                for (int i = (listLayers.size() - 1); i >= 0; i--) {
155
                        FLayer lyr = (FLayer) listLayers.get(i);
156 16998 nbrodin
157 17048 nbrodin
                        if (!(lyr instanceof FLyrRasterSE))
158 16998 nbrodin
                                continue;
159
160
                        FLyrRasterSE rLyr = ((FLyrRasterSE)lyr);
161
162 27466 nbrodin
                        if(rLyr.getRenderFilterList() == null || rLyr.getFullEnvelope() == null)
163
                                continue;
164
165 21626 nbrodin
                        //Si no est? activa y/o visible no se dibuja nunca
166
                        if(!rLyr.isVisible()) {
167
                                layersToPaint.put(rLyr, new Boolean(false));
168
                                continue;
169
                        }
170
171
                        //Si tiene rotaci?n se dibuja siempre
172 23719 nbrodin
                        if(rLyr.getAffineTransform() != null) {
173
                                if(        rLyr.getAffineTransform().getShearX() != 0 ||
174
                                                rLyr.getAffineTransform().getShearY() != 0) {
175
                                        layersToPaint.put(rLyr, new Boolean(true));
176
                                        continue;
177
                                }
178 16998 nbrodin
                        }
179 23719 nbrodin
180 21626 nbrodin
                        //Si es la primera metemos el extent en la lista y se dibuja
181 27466 nbrodin
                        //Si no es la primera y no intersecta con ning?n extent. Metemos el extent y dibujamos
182 21626 nbrodin
                        LayerIntersection li = areIntersecting(extentList, rLyr);
183 22019 nbrodin
                        if((i == (listLayers.size() - 1)) || li == null) {
184 24387 nbrodin
                                boolean colorTableAlpha = false;
185 27466 nbrodin
                                if(rLyr.getRenderFilterList() != null) {
186
                                        RasterFilter rf = rLyr.getRenderFilterList().get("colortable");
187
                                        if(rf != null && rf instanceof ColorTableFilter)
188
                                                colorTableAlpha = ((ColorTableFilter)rf).getColorTable().hasAlpha();
189
                                }
190 24387 nbrodin
                                extentList.add(new LayerIntersection(rLyr.getFullRasterExtent(), (rLyr.existsAlphaBand() || rLyr.isTransparent() || colorTableAlpha)));
191 21626 nbrodin
                                layersToPaint.put(rLyr, new Boolean(true));
192
                                continue;
193
                        }
194
195
                        //Si con la que intersecta no tiene transparencia no se dibuja
196
                        if(li != null && !li.hasTransparency) {
197 17048 nbrodin
                                layersToPaint.put(rLyr, new Boolean(false));
198 21626 nbrodin
                                continue;
199 16998 nbrodin
                        }
200 21626 nbrodin
201
                        if(!rLyr.isTransparent())
202
                                li.hasTransparency = false;
203
                        layersToPaint.put(rLyr, new Boolean(true));
204 16998 nbrodin
                }
205 24190 nbrodin
206 21626 nbrodin
                mapContextStrategy.put(mapContext, layersToPaint);
207 16998 nbrodin
        }
208
209 24190 nbrodin
210 16998 nbrodin
        /**
211 22019 nbrodin
         * Obtiene la lista de capas del TOC. Si hay capas agrupadas lo tiene en cuenta y mira
212
         * dentro de la agrupaci?n.
213
         * @param srcLyrs
214
         * @param destLyrs
215
         * @return
216
         */
217 24190 nbrodin
        public static ArrayList getLayerList(FLayers srcLyrs, ArrayList destLyrs) {
218 22019 nbrodin
                for (int i = 0; i < srcLyrs.getLayersCount(); i++) {
219
                        if(srcLyrs.getLayer(i) instanceof FLyrRasterSE)
220
                                destLyrs.add(srcLyrs.getLayer(i));
221
                        if(srcLyrs.getLayer(i) instanceof FLayers)
222
                                destLyrs = getLayerList((FLayers)srcLyrs.getLayer(i), destLyrs);
223
                }
224
                return destLyrs;
225
        }
226
227
        /**
228 16998 nbrodin
         * Comprueba si la capa que se pasa por par?metro est? oculta por alguno
229
         * de los extent de la lista
230
         * @param extentList Lista de extensiones
231
         * @param lyr Capa raster
232
         * @return
233
         */
234 21626 nbrodin
        private LayerIntersection areIntersecting(ArrayList extentList, FLyrRasterSE lyr) {
235 16998 nbrodin
                for (int i = 0; i < extentList.size(); i++) {
236
                        Extent ex = lyr.getFullRasterExtent();
237 21626 nbrodin
                        Extent ex1 = ((LayerIntersection)extentList.get(i)).extent;
238 21628 nbrodin
                        if(RasterUtilities.isInside(ex, ex1))
239 21626 nbrodin
                                return ((LayerIntersection)extentList.get(i));
240 16998 nbrodin
                }
241 21626 nbrodin
                return null;
242 16998 nbrodin
        }
243
244
        /**
245
         * Obtiene un TreeMap con la lista de capas que se dibujan. Si se al TreeMap se
246
         * le pasa como par?metro una capa raster y devuelve null es que no se dibuja.
247
         *
248
         * @return TreeMap con la lista de capas a dibujar.
249
         */
250
        public HashMap getStrategy() {
251 21626 nbrodin
                return (HashMap)mapContextStrategy.get(mapContext);
252 16998 nbrodin
        }
253
}