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 | } |