svn-gvsig-desktop / tags / v1_1_Build_1015 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapContext.java @ 13679
History | View | Annotate | Download (46.9 KB)
1 | 6878 | cesar | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2004 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 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | package com.iver.cit.gvsig.fmap; |
||
42 | |||
43 | 13411 | ppiqueras | import java.awt.Graphics; |
44 | 6878 | cesar | import java.awt.Graphics2D; |
45 | import java.awt.RenderingHints; |
||
46 | import java.awt.Toolkit; |
||
47 | import java.awt.geom.Rectangle2D; |
||
48 | import java.awt.image.BufferedImage; |
||
49 | import java.util.ArrayList; |
||
50 | 8765 | jjdelcerro | import java.util.List; |
51 | import java.util.prefs.Preferences; |
||
52 | 6878 | cesar | |
53 | 9013 | caballero | import javax.print.attribute.PrintRequestAttributeSet; |
54 | |||
55 | 6878 | cesar | import org.cresques.cts.ICoordTrans; |
56 | import org.cresques.cts.IProjection; |
||
57 | import org.cresques.geo.Projected; |
||
58 | |||
59 | import com.iver.cit.gvsig.fmap.layers.CancelationException; |
||
60 | import com.iver.cit.gvsig.fmap.layers.FLayer; |
||
61 | import com.iver.cit.gvsig.fmap.layers.FLayers; |
||
62 | import com.iver.cit.gvsig.fmap.layers.GraphicLayer; |
||
63 | import com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent; |
||
64 | import com.iver.cit.gvsig.fmap.layers.LayerCollectionListener; |
||
65 | import com.iver.cit.gvsig.fmap.layers.LayerDrawEvent; |
||
66 | import com.iver.cit.gvsig.fmap.layers.LayerDrawingListener; |
||
67 | import com.iver.cit.gvsig.fmap.layers.LayerPositionEvent; |
||
68 | import com.iver.cit.gvsig.fmap.layers.LegendListener; |
||
69 | import com.iver.cit.gvsig.fmap.layers.XMLException; |
||
70 | import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData; |
||
71 | import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable; |
||
72 | import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable; |
||
73 | import com.iver.cit.gvsig.fmap.operations.strategies.SelectedZoomVisitor; |
||
74 | import com.iver.cit.gvsig.fmap.operations.strategies.VisitException; |
||
75 | import com.iver.utiles.XMLEntity; |
||
76 | import com.iver.utiles.swing.threads.Cancellable; |
||
77 | |||
78 | /**
|
||
79 | 13411 | ppiqueras | * <p>The <code>MapContext</code> class represents the model and control around the layers of a map of a view.</p>
|
80 | *
|
||
81 | * <p>An instance of <code>MapContext</code> is made up with:
|
||
82 | * <ul>
|
||
83 | * <li>a hierarchy of {@link FLayers FLayers} nodes
|
||
84 | * <li>a {@link GraphicLayer GraphicLayer} layer
|
||
85 | * <li>a {@link ViewPort ViewPort}
|
||
86 | * <li>an {@link EventBuffer EventButter}
|
||
87 | * <li>some {@link com.iver.cit.gvsig.fmap.rendering.LegendListener LegendListener}s
|
||
88 | * <li>some {@link LayerDrawingListener LayerDrawingListener}s
|
||
89 | * <li>some {@link LayerEventListener LayerEventListener}s
|
||
90 | * <li>some {@link ErrorListener ErrorListener}s
|
||
91 | * </ul>
|
||
92 | * </p>
|
||
93 | 6878 | cesar | *
|
94 | * @author Fernando Gonz?lez Cort?s
|
||
95 | */
|
||
96 | public class MapContext implements Projected { |
||
97 | 13411 | ppiqueras | /**
|
98 | 13483 | ppiqueras | * <p>Defines the value which a unit of a distance measurement must be divided to obtain its equivalent <b>in meters</b>.</p>
|
99 | 13411 | ppiqueras | *
|
100 | * <p><b><i>Conversion values of distance measurements:</i></b>
|
||
101 | * <ul>
|
||
102 | * <li><code>MapContext.CHANGEM[0]</code>: kilometer
|
||
103 | * <li><code>MapContext.CHANGEM[1]</code>: meter
|
||
104 | * <li><code>MapContext.CHANGEM[2]</code>: centimeter
|
||
105 | * <li><code>MapContext.CHANGEM[3]</code>: millimeter
|
||
106 | 13483 | ppiqueras | * <li><code>MapContext.CHANGEM[4]</code>: statute mile
|
107 | 13411 | ppiqueras | * <li><code>MapContext.CHANGEM[5]</code>: yard
|
108 | * <li><code>MapContext.CHANGEM[6]</code>: foot
|
||
109 | * <li><code>MapContext.CHANGEM[7]</code>: inch
|
||
110 | * <li><code>MapContext.CHANGEM[8]</code>: grade
|
||
111 | * </ul>
|
||
112 | *
|
||
113 | * <p><h3>Examples:</h3>
|
||
114 | 13483 | ppiqueras | * <pre>1 statute mile / MapContext.CHANGEM[4] = X meters</pre>
|
115 | 13411 | ppiqueras | * <pre>1 kilometer / MapContext.CHANGEM[0] = X meters</pre>
|
116 | * <pre>1 grade / MapContext.CHANGEM[8] = X meters</pre>
|
||
117 | * </p>
|
||
118 | *
|
||
119 | * <p><h3>Grade conversion value: <code>MapContext.CHANGEM[8]</code></h3>
|
||
120 | * The value of <code>MapContext.CHANGEM[8]</code> represents the meters of a straight line between two
|
||
121 | * points on the Earth surface that are 1 grade far each other of the center of the Earth. This value has been calculated using
|
||
122 | * a radius approximated of R<sub>Earth</sub>=6.37846082678100774672e6 meters, according these equations:
|
||
123 | 13483 | ppiqueras | * <pre>D = 2 * (sin (1)) * R<sub>Earth</sub></pre>
|
124 | * <pre>MapContext.CHANGEM[8] = 1 / D</pre>
|
||
125 | 13411 | ppiqueras | * <h4>Explanation:</h4>
|
126 | * We get an isosceles triangle with the center of the Earth and the 2 points on the surface. This triangle can be divided into
|
||
127 | 13483 | ppiqueras | * two rectangle triangles. We know two values, the angle of 1 grade, that will be 0.50 grades in each triangle, and the Earth radius that
|
128 | 13411 | ppiqueras | * is the hypotenuse. Then we apply trigonometry and get the distance <i>D</i> between both points on the Earth surface.</p>
|
129 | * <p>Now we only must invert that value to obtain <code>MapContext.CHANGEM[8]</code>.</p>
|
||
130 | */
|
||
131 | 6878 | cesar | public static final double[] CHANGEM = { 1000, 1, 0.01, 0.001, 1609.344, |
132 | 10525 | caballero | 0.9144, 0.3048, 0.0254, 1/8.983152841195214E-6 }; |
133 | 6878 | cesar | |
134 | 13411 | ppiqueras | /**
|
135 | 13483 | ppiqueras | * <p>Defines the value which a unit of a distance measurement must be divided to obtain its equivalent <b>in centimeters</b>.</p>
|
136 | 13411 | ppiqueras | *
|
137 | * <p><b><i>Conversion values of distance measurements:</i></b>
|
||
138 | * <ul>
|
||
139 | * <li><code>MapContext.CHANGEM[0]</code>: kilometer
|
||
140 | * <li><code>MapContext.CHANGEM[1]</code>: meter
|
||
141 | * <li><code>MapContext.CHANGEM[2]</code>: centimeter
|
||
142 | * <li><code>MapContext.CHANGEM[3]</code>: millimeter
|
||
143 | 13483 | ppiqueras | * <li><code>MapContext.CHANGEM[4]</code>: statute mile
|
144 | 13411 | ppiqueras | * <li><code>MapContext.CHANGEM[5]</code>: yard
|
145 | * <li><code>MapContext.CHANGEM[6]</code>: foot
|
||
146 | * <li><code>MapContext.CHANGEM[7]</code>: inch
|
||
147 | * <li><code>MapContext.CHANGEM[8]</code>: grade
|
||
148 | * </ul>
|
||
149 | *
|
||
150 | * <p><h3>Examples:</h3>
|
||
151 | 13483 | ppiqueras | * <pre>1 statute mile / MapContext.CHANGEM[4] = X centimeters</pre>
|
152 | * <pre>1 kilometer / MapContext.CHANGEM[0] = X centimeters</pre>
|
||
153 | * <pre>1 grade / MapContext.CHANGEM[8] = X centimeters</pre>
|
||
154 | 13411 | ppiqueras | * </p>
|
155 | *
|
||
156 | * <p><h3>Grade conversion value: <code>MapContext.CHANGEM[8]</code></h3>
|
||
157 | * The value of <code>MapContext.CHANGEM[8]</code> represents the centimeters of a straight line between two
|
||
158 | * points on the Earth surface that are 1 grade far each other of the center of the Earth. This value has been calculated using
|
||
159 | * a radius approximated of R<sub>Earth</sub>=6.37846082678100774672e6 meters, according these equations:
|
||
160 | 13483 | ppiqueras | * <pre>D = 2 * (sin (1)) * R<sub>Earth</sub></pre>
|
161 | * <pre>MapContext.CHANGEM[8] = 1 / D</pre>
|
||
162 | 13411 | ppiqueras | * <h4>Explanation:</h4>
|
163 | * We get an isosceles triangle with the center of the Earth and the 2 points on the surface. This triangle can be divided into
|
||
164 | 13483 | ppiqueras | * two rectangle triangles. We know two values, the angle of 1 grade, that will be 0.50 grades in each triangle, and the Earth radius that
|
165 | 13411 | ppiqueras | * is the hypotenuse. Then we apply trigonometry and get the distance <i>D</i> between both points on the Earth surface.</p>
|
166 | * <p>Now we only must invert that value to obtain <code>MapContext.CHANGEM[8]</code>.</p>
|
||
167 | */
|
||
168 | 6878 | cesar | public static final double[] CHANGE = { 100000, 100, 1, 0.1, 160934.4, |
169 | 10525 | caballero | 91.44, 30.48, 2.54, 1/8.983152841195214E-4 }; |
170 | 6878 | cesar | |
171 | 13411 | ppiqueras | /**
|
172 | *
|
||
173 | */
|
||
174 | 6878 | cesar | public static final int EQUALS = 0; |
175 | |||
176 | 13411 | ppiqueras | /**
|
177 | *
|
||
178 | */
|
||
179 | 6878 | cesar | public static final int DISJOINT = 1; |
180 | |||
181 | 13411 | ppiqueras | /**
|
182 | *
|
||
183 | */
|
||
184 | 6878 | cesar | public static final int INTERSECTS = 2; |
185 | |||
186 | 13411 | ppiqueras | /**
|
187 | *
|
||
188 | */
|
||
189 | 6878 | cesar | public static final int TOUCHES = 3; |
190 | |||
191 | 13411 | ppiqueras | /**
|
192 | *
|
||
193 | */
|
||
194 | 6878 | cesar | public static final int CROSSES = 4; |
195 | |||
196 | 13411 | ppiqueras | /**
|
197 | *
|
||
198 | */
|
||
199 | 6878 | cesar | public static final int WITHIN = 5; |
200 | |||
201 | 13411 | ppiqueras | /**
|
202 | *
|
||
203 | */
|
||
204 | 6878 | cesar | public static final int CONTAINS = 6; |
205 | |||
206 | 13411 | ppiqueras | /**
|
207 | *
|
||
208 | */
|
||
209 | 6878 | cesar | public static final int OVERLAPS = 7; |
210 | |||
211 | 13411 | ppiqueras | /**
|
212 | * A hierarchy of {@link FLayers FLayers} nodes.
|
||
213 | 13483 | ppiqueras | *
|
214 | * @see #getLayers()
|
||
215 | * @see #print(Graphics2D, double, PrintRequestAttributeSet)
|
||
216 | 13411 | ppiqueras | */
|
217 | 8765 | jjdelcerro | protected FLayers layers;
|
218 | 6878 | cesar | |
219 | 13411 | ppiqueras | /**
|
220 | * A layer with graphical items: geometries and symbols.
|
||
221 | 13483 | ppiqueras | *
|
222 | * @see #getGraphicsLayer()
|
||
223 | * @see #setGraphicsLayer(GraphicLayer)
|
||
224 | * @see #drawGraphics(BufferedImage, Graphics2D, Cancellable, double)
|
||
225 | * @see #print(Graphics2D, double, PrintRequestAttributeSet)
|
||
226 | 13411 | ppiqueras | */
|
227 | 6878 | cesar | private GraphicLayer tracLayer = new GraphicLayer(); |
228 | |||
229 | 13411 | ppiqueras | /**
|
230 | 13586 | ppiqueras | * Information for draw layers in a view.
|
231 | 13483 | ppiqueras | *
|
232 | * @see #getViewPort()
|
||
233 | * @see #setViewPort(ViewPort)
|
||
234 | 13411 | ppiqueras | */
|
235 | 6878 | cesar | private ViewPort viewPort;
|
236 | |||
237 | // private ArrayList invalidationListeners = new ArrayList();
|
||
238 | 13411 | ppiqueras | |
239 | /**
|
||
240 | * Array list with all {@link LegendListener LegendListener} registered to this map.
|
||
241 | 13483 | ppiqueras | *
|
242 | * @see #addLayerListener(LegendListener)
|
||
243 | * @see #removeLayerListener(LegendListener)
|
||
244 | * @see #callLegendChanged()
|
||
245 | 13411 | ppiqueras | */
|
246 | 6878 | cesar | private ArrayList legendListeners = new ArrayList(); |
247 | |||
248 | 13411 | ppiqueras | /**
|
249 | * Array list with all {@link LayerDrawingListener LayerDrawingListener} registered to this map.
|
||
250 | 13483 | ppiqueras | *
|
251 | * @see #addLayerDrawingListener(LayerDrawingListener)
|
||
252 | * @see #removeLayerDrawListener(LayerDrawingListener)
|
||
253 | * @see #fireLayerDrawingEvent(LayerDrawEvent)
|
||
254 | 13411 | ppiqueras | */
|
255 | 6878 | cesar | private ArrayList layerDrawingListeners = new ArrayList(); |
256 | |||
257 | 13411 | ppiqueras | /**
|
258 | * <p>Buffer that is used to store and eject events produced on this map:
|
||
259 | * <ul>
|
||
260 | * <li>Layer collection events.
|
||
261 | * <li>View port events.
|
||
262 | * <li>Atomic events.
|
||
263 | * <li>Layer events.
|
||
264 | * <li>Legend events on a {@link Classificable Classificable} layer.
|
||
265 | * <li>Selection events on an {@link AlphanumericData AlphanumericData} data layer.
|
||
266 | * </ul>
|
||
267 | 13483 | ppiqueras | * </p>
|
268 | *
|
||
269 | * @see #addAtomicEventListener(AtomicEventListener)
|
||
270 | * @see #removeAtomicEventListener(AtomicEventListener)
|
||
271 | * @see #beginAtomicEvent()
|
||
272 | * @see #endAtomicEvent()
|
||
273 | 13411 | ppiqueras | */
|
274 | 6878 | cesar | private EventBuffer eventBuffer = new EventBuffer(); |
275 | |||
276 | 13411 | ppiqueras | /**
|
277 | * Event listener for the collection of layers of this map.
|
||
278 | */
|
||
279 | 6878 | cesar | private LayerEventListener layerEventListener = null; |
280 | |||
281 | 13411 | ppiqueras | /**
|
282 | * List with information of all errors produced on all layers.
|
||
283 | 13483 | ppiqueras | *
|
284 | * @see #addLayerError(String)
|
||
285 | * @see #getLayersError()
|
||
286 | * @see #clearErrors()
|
||
287 | 13411 | ppiqueras | */
|
288 | 6878 | cesar | private ArrayList layersError = new ArrayList(); |
289 | |||
290 | 13411 | ppiqueras | /**
|
291 | * Array list with all {@link ErrorListener ErrorListener} registered to this map.
|
||
292 | 13483 | ppiqueras | *
|
293 | * @see #addErrorListener(ErrorListener)
|
||
294 | * @see #removeErrorListener(LegendListener)
|
||
295 | * @see #callNewErrorEvent(ErrorEvent)
|
||
296 | * @see #reportDriverExceptions(String, List)
|
||
297 | 13411 | ppiqueras | */
|
298 | 6878 | cesar | private ArrayList errorListeners = new ArrayList(); |
299 | |||
300 | // public static ResourceBundle myResourceBundle =
|
||
301 | // ResourceBundle.getBundle("FMap");
|
||
302 | 13411 | ppiqueras | |
303 | /**
|
||
304 | * <p>Default zoom in factor.</p>
|
||
305 | * <p>Doing a <i>zoom in</i> operation, decreases the focal distance and increases the eyesight angle to the surface. This allows view an smaller
|
||
306 | * area but with the items bigger.</p>
|
||
307 | */
|
||
308 | 6878 | cesar | public static double ZOOMINFACTOR=2; |
309 | 13411 | ppiqueras | |
310 | /**
|
||
311 | * <p>Default zoom out factor.</p>
|
||
312 | * <p>Doing a <i>zoom out</i> operation, increases the focal distance and decreases the eyesight angle to the surface. This allows view a bigger
|
||
313 | * area but with the items smaller.</p>
|
||
314 | */
|
||
315 | 6878 | cesar | public static double ZOOMOUTFACTOR=0.5; |
316 | 13411 | ppiqueras | |
317 | 6878 | cesar | /**
|
318 | 13411 | ppiqueras | * <p>Creates a new map context with the drawing information defined in the view port argument, and
|
319 | * without layers.</p>
|
||
320 | 6878 | cesar | *
|
321 | 13411 | ppiqueras | * @param vp information for drawing the layers of this map as a view
|
322 | 6878 | cesar | */
|
323 | public MapContext(ViewPort vp) {
|
||
324 | 8765 | jjdelcerro | this.layers = new FLayers(this, null); |
325 | |||
326 | 6878 | cesar | layerEventListener = new LayerEventListener();
|
327 | layers.addLayerCollectionListener(layerEventListener); |
||
328 | layers.addLayerCollectionListener(eventBuffer); |
||
329 | |||
330 | 8765 | jjdelcerro | setViewPort(vp); |
331 | } |
||
332 | |||
333 | 13411 | ppiqueras | /**
|
334 | * <p>Creates a new map context with the layers and the drawing information defined in the view port arguments.</p>
|
||
335 | *
|
||
336 | * @param fLayers the initial hierarchy of nodes of layers that this map will have
|
||
337 | * @param vp information for drawing the layers of this map as a view
|
||
338 | */
|
||
339 | 8765 | jjdelcerro | public MapContext(FLayers fLayers, ViewPort vp) {
|
340 | this.layers = fLayers;
|
||
341 | |||
342 | layerEventListener = new LayerEventListener();
|
||
343 | layers.addLayerCollectionListener(layerEventListener); |
||
344 | layers.addLayerCollectionListener(eventBuffer); |
||
345 | |||
346 | setViewPort(vp); |
||
347 | } |
||
348 | |||
349 | /**
|
||
350 | 13411 | ppiqueras | * <p>Reports to all driver error listeners registered of a bundle of driver exceptions caused in the same map atomic transaction.</p>
|
351 | *
|
||
352 | * @param introductoryText introductory text specified by developer. If <code>null</code>, use ""
|
||
353 | * @param driverExceptions list with a bundle of driver exceptions caught during an atomic event
|
||
354 | 13483 | ppiqueras | *
|
355 | * @see #addErrorListener(ErrorListener)
|
||
356 | * @see #removeErrorListener(LegendListener)
|
||
357 | * @see #callNewErrorEvent(ErrorEvent)
|
||
358 | 8765 | jjdelcerro | */
|
359 | public synchronized void reportDriverExceptions(String introductoryText, |
||
360 | List driverExceptions){
|
||
361 | for (int i = 0; i < errorListeners.size(); i++) { |
||
362 | ((ErrorListener) errorListeners.get(i)).
|
||
363 | reportDriverExceptions(introductoryText, driverExceptions); |
||
364 | 6878 | cesar | } |
365 | } |
||
366 | |||
367 | /**
|
||
368 | 13483 | ppiqueras | * <p>Adds the specified legend listener (if didn't exist) to receive legend events from this map.</p>
|
369 | 6878 | cesar | *
|
370 | 13411 | ppiqueras | * @param listener the legend listener
|
371 | 13483 | ppiqueras | *
|
372 | * @see #removeLayerListener(LegendListener)
|
||
373 | * @see #callLegendChanged()
|
||
374 | 6878 | cesar | */
|
375 | public void addLayerListener(LegendListener listener) { |
||
376 | 8765 | jjdelcerro | if (!legendListeners.contains(listener))
|
377 | legendListeners.add(listener); |
||
378 | 6878 | cesar | } |
379 | 13483 | ppiqueras | // SUGERENCIA DE PABLO
|
380 | // public void addLegendListener(LegendListener listener) {
|
||
381 | // if (!legendListeners.contains(listener))
|
||
382 | // legendListeners.add(listener);
|
||
383 | // }
|
||
384 | 6878 | cesar | |
385 | 13411 | ppiqueras | /**
|
386 | * <p>Adds the specified layer drawing listener to receive drawing events from layers of this map.</p>
|
||
387 | *
|
||
388 | * @param listener the listener to add
|
||
389 | 13483 | ppiqueras | *
|
390 | * @see #removeLayerDrawListener(LayerDrawingListener)
|
||
391 | * @see #fireLayerDrawingEvent(LayerDrawEvent)
|
||
392 | 13411 | ppiqueras | */
|
393 | 6878 | cesar | public void addLayerDrawingListener(LayerDrawingListener listener) { |
394 | layerDrawingListeners.add(listener); |
||
395 | } |
||
396 | |||
397 | 13411 | ppiqueras | /**
|
398 | * <p>Removes the specified layer drawing listener from this map.</p>
|
||
399 | *
|
||
400 | * @param listener the listener to remove
|
||
401 | 13483 | ppiqueras | *
|
402 | * @see #addLayerDrawingListener(LayerDrawingListener)
|
||
403 | * @see #fireLayerDrawingEvent(LayerDrawEvent)
|
||
404 | 13411 | ppiqueras | */
|
405 | 6878 | cesar | public void removeLayerDrawListener(LayerDrawingListener listener) { |
406 | layerDrawingListeners.remove(listener); |
||
407 | } |
||
408 | |||
409 | 13411 | ppiqueras | /**
|
410 | * <p>Adds the specified error listener to receive error events from this map.</p>
|
||
411 | *
|
||
412 | * @param listener the listener to add
|
||
413 | 13483 | ppiqueras | *
|
414 | * @see #removeErrorListener(LegendListener)
|
||
415 | * @see #callNewErrorEvent(ErrorEvent)
|
||
416 | * @see #reportDriverExceptions(String, List)
|
||
417 | 13411 | ppiqueras | */
|
418 | 6878 | cesar | public void addErrorListener(ErrorListener listener) { |
419 | errorListeners.add(listener); |
||
420 | } |
||
421 | |||
422 | 13411 | ppiqueras | /**
|
423 | * <p>Removes the specified error listener from this map.</p>
|
||
424 | *
|
||
425 | * @param listener the listener to remove
|
||
426 | 13483 | ppiqueras | *
|
427 | * @see #addErrorListener(ErrorListener)
|
||
428 | * @see #callNewErrorEvent(ErrorEvent)
|
||
429 | * @see #reportDriverExceptions(String, List)
|
||
430 | 13411 | ppiqueras | */
|
431 | 6878 | cesar | public void removeErrorListener(LegendListener listener) { |
432 | legendListeners.remove(listener); |
||
433 | } |
||
434 | 13483 | ppiqueras | // SUGERENCIA DE PABLO:
|
435 | //public void removeErrorListener(ErrorListener listener) {
|
||
436 | // errorListeners.remove(listener);
|
||
437 | //}
|
||
438 | 6878 | cesar | |
439 | /**
|
||
440 | 13411 | ppiqueras | * <p>Notifies to all legend listeners registered, that one legend has changed.</p>
|
441 | 13483 | ppiqueras | * <p>This method must be call only if it's wanted to reflect a legend change.</p>
|
442 | *
|
||
443 | * @see #addLayerListener(LegendListener)
|
||
444 | * @see #removeLayerListener(LegendListener)
|
||
445 | 6878 | cesar | */
|
446 | public synchronized void callLegendChanged() { |
||
447 | for (int i = 0; i < legendListeners.size(); i++) { |
||
448 | ((LegendListener) legendListeners.get(i)).legendChanged(null);
|
||
449 | } |
||
450 | // getLayers().moveTo(0,0);
|
||
451 | } |
||
452 | |||
453 | 13411 | ppiqueras | /**
|
454 | * <p>Fires a layer drawing event to all {@link LayerDrawingListener LayerDrawingListener} listeners registered,
|
||
455 | * distinguishing the kind of event.</p>
|
||
456 | *
|
||
457 | * @param e the event
|
||
458 | 13483 | ppiqueras | *
|
459 | * @see #addLayerDrawingListener(LayerDrawingListener)
|
||
460 | * @see #removeLayerDrawListener(LayerDrawingListener)
|
||
461 | 13411 | ppiqueras | */
|
462 | 6878 | cesar | public synchronized void fireLayerDrawingEvent(LayerDrawEvent e) { |
463 | for (int i = 0; i < layerDrawingListeners.size(); i++) |
||
464 | { |
||
465 | LayerDrawingListener listener = (LayerDrawingListener) layerDrawingListeners.get(i); |
||
466 | switch (e.getEventType())
|
||
467 | { |
||
468 | case LayerDrawEvent.LAYER_BEFORE_DRAW:
|
||
469 | listener.beforeLayerDraw(e); |
||
470 | break;
|
||
471 | case LayerDrawEvent.LAYER_AFTER_DRAW:
|
||
472 | listener.afterLayerDraw(e); |
||
473 | break;
|
||
474 | case LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW:
|
||
475 | listener.beforeGraphicLayerDraw(e); |
||
476 | break;
|
||
477 | case LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW:
|
||
478 | listener.afterLayerGraphicDraw(e); |
||
479 | break;
|
||
480 | } |
||
481 | } |
||
482 | // getLayers().moveTo(0,0);
|
||
483 | } |
||
484 | |||
485 | 13411 | ppiqueras | /**
|
486 | * <p>Notifies to all error listeners registered, that one error has been produced.</p>
|
||
487 | *
|
||
488 | * @param e the event with information of the error
|
||
489 | 13483 | ppiqueras | *
|
490 | * @see #addErrorListener(ErrorListener)
|
||
491 | * @see #removeErrorListener(LegendListener)
|
||
492 | * @see #reportDriverExceptions(String, List)
|
||
493 | 13411 | ppiqueras | */
|
494 | 6878 | cesar | public synchronized void callNewErrorEvent(ErrorEvent e) { |
495 | for (int i = 0; i < errorListeners.size(); i++) { |
||
496 | ((ErrorListener) errorListeners.get(i)).errorThrown(e);
|
||
497 | } |
||
498 | // getLayers().moveTo(0,0);
|
||
499 | } |
||
500 | |||
501 | /**
|
||
502 | 13411 | ppiqueras | * <p>Removes the specified layer listener from this map.</p>
|
503 | *
|
||
504 | * @param listener the listener to remove
|
||
505 | 13483 | ppiqueras | *
|
506 | * @see #addLayerListener(LegendListener)
|
||
507 | * @see #callLegendChanged()
|
||
508 | 6878 | cesar | */
|
509 | public void removeLayerListener(LegendListener listener) { |
||
510 | legendListeners.remove(listener); |
||
511 | } |
||
512 | 13483 | ppiqueras | // SUGERENCIA DE PABLO:
|
513 | // public void removeLegendListener(LegendListener listener) {
|
||
514 | // legendListeners.remove(listener);
|
||
515 | // }
|
||
516 | 6878 | cesar | |
517 | /**
|
||
518 | 13411 | ppiqueras | * <p>Returns the hierarchy of {@link FLayers FLayers} nodes stored in this map.</p>
|
519 | 6878 | cesar | *
|
520 | 13411 | ppiqueras | * @return the hierarchy of nodes of layers stored in this map
|
521 | 6878 | cesar | */
|
522 | public FLayers getLayers() {
|
||
523 | return layers;
|
||
524 | } |
||
525 | |||
526 | /**
|
||
527 | 13411 | ppiqueras | * <p>Draws the visible layers of this map according its view port, on the image parameter.</p>
|
528 | 6878 | cesar | *
|
529 | 13411 | ppiqueras | * @param b image with an accessible buffer of image data
|
530 | 6878 | cesar | */
|
531 | public void drawLabels(BufferedImage b) { |
||
532 | } |
||
533 | |||
534 | /**
|
||
535 | 13411 | ppiqueras | * @see #redraw()
|
536 | 6878 | cesar | */
|
537 | public void invalidate() { |
||
538 | 13411 | ppiqueras | // SUGERENCIA DE PABLO:
|
539 | // redraw();
|
||
540 | |||
541 | 6878 | cesar | getLayers().moveTo(0, 0); |
542 | } |
||
543 | |||
544 | /**
|
||
545 | 13411 | ppiqueras | * <p>Prints the layers of this map using the {@link Graphics2D Graphics2D} argument, that usually is
|
546 | * the {@link Graphics Graphics} of the printer.</p>
|
||
547 | 6878 | cesar | *
|
548 | 13483 | ppiqueras | * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
|
549 | * @param scale the scale of the view. Must be between {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
|
||
550 | 13411 | ppiqueras | * @param properties a set with the settings to be applied to a whole print job and to all the documents in the print job
|
551 | 6878 | cesar | *
|
552 | 13411 | ppiqueras | * @throws DriverException if fails using some driver.
|
553 | *
|
||
554 | * @see FLayers#print(Graphics2D, ViewPort, Cancellable, double, PrintRequestAttributeSet)
|
||
555 | * @see GraphicLayer#draw(BufferedImage, Graphics2D, ViewPort, Cancellable, double)
|
||
556 | 6878 | cesar | */
|
557 | 9013 | caballero | public void print(Graphics2D g, double scale, PrintRequestAttributeSet properties) throws DriverException { |
558 | 6878 | cesar | RenderingHints renderHints = new RenderingHints( |
559 | RenderingHints.KEY_ANTIALIASING,
|
||
560 | RenderingHints.VALUE_ANTIALIAS_ON);
|
||
561 | renderHints.put(RenderingHints.KEY_RENDERING,
|
||
562 | RenderingHints.VALUE_RENDER_QUALITY);
|
||
563 | g.setRenderingHints(renderHints); |
||
564 | |||
565 | Cancellable cancel = new Cancellable() {
|
||
566 | 13411 | ppiqueras | /*
|
567 | * @see com.iver.utiles.swing.threads.Cancellable#isCanceled()
|
||
568 | */
|
||
569 | 6878 | cesar | public boolean isCanceled() { |
570 | return false; |
||
571 | } |
||
572 | |||
573 | 13411 | ppiqueras | /*
|
574 | * @see com.iver.utiles.swing.threads.Cancellable#setCanceled(boolean)
|
||
575 | */
|
||
576 | 6878 | cesar | public void setCanceled(boolean canceled) { |
577 | // No queremos que se pueda cancelar la impresi?n.
|
||
578 | |||
579 | } |
||
580 | }; |
||
581 | 9013 | caballero | layers.print(g, viewPort, cancel, scale, properties); |
582 | 6878 | cesar | tracLayer.draw(null, g, viewPort, cancel, scale);
|
583 | } |
||
584 | |||
585 | /**
|
||
586 | 13508 | ppiqueras | * <p>Returns a new map with the information of the <code>vp</code> argument, and the layers of this map.</p>
|
587 | 6878 | cesar | *
|
588 | 13411 | ppiqueras | * @param vp information for drawing the layers
|
589 | 6878 | cesar | *
|
590 | 13411 | ppiqueras | * @return a new map
|
591 | 6878 | cesar | */
|
592 | public MapContext createNewFMap(ViewPort vp) {
|
||
593 | MapContext ret = new MapContext(vp);
|
||
594 | ret.layers = this.layers;
|
||
595 | |||
596 | return ret;
|
||
597 | } |
||
598 | |||
599 | /**
|
||
600 | 13508 | ppiqueras | * <p>Creates a new independent map, that has a clone of the layers and the view port of this one.</p>
|
601 | 13411 | ppiqueras | * <p>The new map will have the same data source drivers to avoid waste memory, and work faster.</p>
|
602 | 6878 | cesar | *
|
603 | 13411 | ppiqueras | * @return the new map
|
604 | 6878 | cesar | *
|
605 | 13411 | ppiqueras | * @throws XMLException if fails cloning the view port or a layer
|
606 | 13508 | ppiqueras | *
|
607 | * @see FLayer#cloneLayer()
|
||
608 | * @see ViewPort#cloneViewPort()
|
||
609 | 6878 | cesar | */
|
610 | public MapContext cloneFMap() throws XMLException { |
||
611 | 9225 | fjp | ViewPort vp = getViewPort().cloneViewPort(); |
612 | FLayers antLayers = getLayers(); |
||
613 | MapContext ret = new MapContext(vp);
|
||
614 | FLayers aux = new FLayers(ret, null); |
||
615 | for (int i=0; i < antLayers.getLayersCount(); i++) |
||
616 | { |
||
617 | FLayer lyr = antLayers.getLayer(i); |
||
618 | try {
|
||
619 | aux.addLayer(lyr.cloneLayer()); |
||
620 | } catch (Exception e) { |
||
621 | 13418 | caballero | throw new XMLException(e); |
622 | 10525 | caballero | } |
623 | 9225 | fjp | } |
624 | ret.layers = aux; |
||
625 | return ret;
|
||
626 | |||
627 | // return createFromXML(getXMLEntity());
|
||
628 | 6878 | cesar | } |
629 | 13411 | ppiqueras | |
630 | /**
|
||
631 | 13508 | ppiqueras | * Like {@linkplain #cloneFMap()}, but now doesn't clone the layers, rather copies them.
|
632 | 13411 | ppiqueras | *
|
633 | * @return the new map
|
||
634 | */
|
||
635 | 8887 | fjp | public MapContext cloneToDraw() {
|
636 | ViewPort vp = getViewPort().cloneViewPort(); |
||
637 | MapContext mapContext=new MapContext(getLayers(),vp);
|
||
638 | return mapContext;
|
||
639 | } |
||
640 | 6878 | cesar | |
641 | /**
|
||
642 | * A?ade la capa que se pasa como par?metro al nodo que se pasa como
|
||
643 | * parametro y lanza ProjectionMismatchException si no est?n todas las capas
|
||
644 | * de este FMap en la misma proyecci?n. Lanza un ChildNotAllowedException si
|
||
645 | * la capa no es un FLayers y no permite hijos
|
||
646 | *
|
||
647 | * @param vectorial
|
||
648 | * DOCUMENT ME!
|
||
649 | */
|
||
650 | |||
651 | /*
|
||
652 | * public void addLayer(LayerPath parent, FLayer layer) throws
|
||
653 | * ProjectionMismatchException, ChildrenNotAllowedException {
|
||
654 | * layers.addLayer(parent, layer); } public void removeLayer(LayerPath
|
||
655 | * parent)throws ChildrenNotAllowedException{ layers.removeLayer(parent); }
|
||
656 | */
|
||
657 | |||
658 | /**
|
||
659 | 13508 | ppiqueras | * <p>Adds a layer to the group of layers that are at a upper level in the tree.</p>
|
660 | 6878 | cesar | *
|
661 | 13411 | ppiqueras | * @param vectorial the layer to add
|
662 | 6878 | cesar | */
|
663 | public void addToTrackLayer(FLayer vectorial) { |
||
664 | } |
||
665 | |||
666 | /**
|
||
667 | 13411 | ppiqueras | * <p>Returns the scale of the view in the screen.</p>
|
668 | 6878 | cesar | *
|
669 | 13483 | ppiqueras | * @return one of this values:
|
670 | 13411 | ppiqueras | * <ul>
|
671 | 13483 | ppiqueras | * <li>the scale of the adjusted extent scale of the view in the screen
|
672 | 13411 | ppiqueras | * <li><code>-1</code> if there is no image
|
673 | * <li><code>0</code> if there is no extent defined for the image
|
||
674 | * </ul>
|
||
675 | 13483 | ppiqueras | *
|
676 | * @see #setScaleView(long)
|
||
677 | * @see ViewPort#getAdjustedExtent()
|
||
678 | * @see IProjection#getScale(double, double, double, double)
|
||
679 | 6878 | cesar | */
|
680 | public long getScaleView() { |
||
681 | 8765 | jjdelcerro | Preferences prefsResolution = Preferences.userRoot().node( "gvsig.configuration.screen" ); |
682 | 6878 | cesar | Toolkit kit = Toolkit.getDefaultToolkit(); |
683 | 8765 | jjdelcerro | double dpi = prefsResolution.getInt("dpi",kit.getScreenResolution()); |
684 | 6878 | cesar | IProjection proj = viewPort.getProjection(); |
685 | |||
686 | if (viewPort.getImageSize() == null) |
||
687 | return -1; |
||
688 | |||
689 | if (viewPort.getAdjustedExtent() == null) { |
||
690 | return 0; |
||
691 | } |
||
692 | |||
693 | if (proj == null) { |
||
694 | 9552 | caballero | double w = ((viewPort.getImageSize().getWidth() / dpi) * 2.54); |
695 | 12227 | caballero | return (long) (viewPort.getAdjustedExtent().getWidth() / w * CHANGEM[getViewPort() |
696 | .getMapUnits()]/CHANGEM[getViewPort().getDistanceUnits()]); |
||
697 | 6878 | cesar | } |
698 | 12227 | caballero | if (proj.isProjected())
|
699 | return Math.round(proj.getScale((viewPort.getAdjustedExtent().getMinX()*CHANGEM[getViewPort().getMapUnits()])/CHANGEM[getViewPort().getDistanceUnits()], |
||
700 | (viewPort.getAdjustedExtent().getMaxX()*CHANGEM[getViewPort().getMapUnits()])/CHANGEM[getViewPort().getDistanceUnits()], viewPort.getImageSize() |
||
701 | 6878 | cesar | .getWidth(), dpi)); |
702 | 12227 | caballero | return Math.round(proj.getScale((viewPort.getAdjustedExtent().getMinX()*CHANGEM[1])/CHANGEM[getViewPort().getDistanceUnits()], |
703 | (viewPort.getAdjustedExtent().getMaxX()*CHANGEM[1])/CHANGEM[getViewPort().getDistanceUnits()], viewPort.getImageSize()
|
||
704 | .getWidth(), dpi)); |
||
705 | 6878 | cesar | } |
706 | /**
|
||
707 | 13483 | ppiqueras | * <p>Sets the new extent of the view, calculated using the scale argument.</p>
|
708 | * <p>Doesn't updates the scale if there isn't information about the dimension of the image or the
|
||
709 | * adjusted extent.</p>
|
||
710 | 6878 | cesar | *
|
711 | 13411 | ppiqueras | * @param scale the new scale for the view
|
712 | 13483 | ppiqueras | *
|
713 | * @see ViewPort#setProjection(IProjection)
|
||
714 | * @see #getScaleView()
|
||
715 | 6878 | cesar | */
|
716 | public void setScaleView(long scale) { |
||
717 | 10752 | caballero | clearAllCachingImageDrawnLayers(); |
718 | 9552 | caballero | Preferences prefsResolution = Preferences.userRoot().node( "gvsig.configuration.screen" ); |
719 | 6878 | cesar | Toolkit kit = Toolkit.getDefaultToolkit(); |
720 | 9552 | caballero | double dpi = prefsResolution.getInt("dpi",kit.getScreenResolution()); |
721 | 6878 | cesar | if (viewPort.getImageSize() == null) |
722 | return;
|
||
723 | 7196 | caballero | IProjection proj = viewPort.getProjection(); |
724 | 6878 | cesar | if (viewPort.getAdjustedExtent() == null) { |
725 | return;
|
||
726 | } |
||
727 | 12231 | jmvivo | Rectangle2D rec=proj.getExtent(
|
728 | viewPort.getAdjustedExtent(), |
||
729 | scale,viewPort.getImageWidth(), |
||
730 | viewPort.getImageHeight(), |
||
731 | CHANGE[getViewPort().getMapUnits()], |
||
732 | // CHANGEM[getViewPort().getDistanceUnits()],
|
||
733 | dpi); |
||
734 | 12227 | caballero | // double dif=CHANGEM[getViewPort().getDistanceUnits()];
|
735 | // double w=rec.getWidth()/dif;
|
||
736 | // double h=rec.getHeight()/dif;
|
||
737 | // rec.setRect(rec.getCenterX()-w/2,rec.getCenterY()-h/2,w,h);
|
||
738 | 7196 | caballero | getViewPort().setExtent(rec); |
739 | 6878 | cesar | } |
740 | |||
741 | 13483 | ppiqueras | /**
|
742 | 6878 | cesar | * @see org.cresques.geo.Projected#getProjection()
|
743 | 13483 | ppiqueras | *
|
744 | * @see ViewPort#getProjection()
|
||
745 | * @see #setProjection(IProjection)
|
||
746 | * @see #reProject(ICoordTrans)
|
||
747 | 6878 | cesar | */
|
748 | public IProjection getProjection() {
|
||
749 | return getViewPort().getProjection();
|
||
750 | } |
||
751 | |||
752 | /**
|
||
753 | 13411 | ppiqueras | * <p>Sets the new projection.</p>
|
754 | 6878 | cesar | *
|
755 | 13411 | ppiqueras | * @param proj the new projection
|
756 | 13483 | ppiqueras | *
|
757 | * @see #getProjection()
|
||
758 | * @see ViewPort#setProjection(IProjection)
|
||
759 | * @see #reProject(ICoordTrans)
|
||
760 | 6878 | cesar | */
|
761 | public void setProjection(IProjection proj) { |
||
762 | if (getViewPort() != null) { |
||
763 | getViewPort().setProjection(proj); |
||
764 | } |
||
765 | } |
||
766 | |||
767 | 13411 | ppiqueras | /*
|
768 | 6878 | cesar | * @see org.cresques.geo.Projected#reProject(org.cresques.cts.ICoordTrans)
|
769 | */
|
||
770 | public void reProject(ICoordTrans arg0) { |
||
771 | // TODO implementar reprojecci?n (lo que sea eso)
|
||
772 | } |
||
773 | |||
774 | /**
|
||
775 | * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#getSelectionBounds()
|
||
776 | 13483 | ppiqueras | *
|
777 | * @see SelectedZoomVisitor#getSelectBound()
|
||
778 | 6878 | cesar | */
|
779 | public Rectangle2D getSelectionBounds() { |
||
780 | SelectedZoomVisitor visitor = new SelectedZoomVisitor();
|
||
781 | |||
782 | try {
|
||
783 | layers.process(visitor); |
||
784 | } catch (DriverException e1) {
|
||
785 | throw new RuntimeException( |
||
786 | "No se espera que SelectByPointVisitor lance esta excepci?n",
|
||
787 | e1); |
||
788 | } catch (VisitException e) {
|
||
789 | throw new RuntimeException( |
||
790 | "No se espera que SelectByPointVisitor lance esta excepci?n",
|
||
791 | e); |
||
792 | } |
||
793 | |||
794 | return visitor.getSelectBound();
|
||
795 | } |
||
796 | |||
797 | /**
|
||
798 | 13508 | ppiqueras | * <p>Draws this map if its {@link ViewPort ViewPort} has an extent defined:<br>
|
799 | 13411 | ppiqueras | * <ol>
|
800 | 13508 | ppiqueras | * <li>Selects only the layers that have to be drawn: {@linkplain #prepareDrawing(BufferedImage, Graphics2D, double)}.
|
801 | 13411 | ppiqueras | * <li>Sets quality: antialiasing por text and images, and quality rendering.
|
802 | * <li>Draws the layers.
|
||
803 | * <li>Fires a <code>LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW</code>.
|
||
804 | * <li>Draws the graphic layer.
|
||
805 | * <li>Fires a <code>LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW</code>.
|
||
806 | * <li>Invokes the garbage collector and memory clean.
|
||
807 | * </ol></p>
|
||
808 | *
|
||
809 | 13483 | ppiqueras | * @param image buffer used sometimes instead <code>g</code> to accelerate the draw. For example, if two points are as closed that can't be distinguished, draws only one.
|
810 | * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
|
||
811 | 13411 | ppiqueras | * @param cancel an object thread that implements the {@link Cancellable Cancellable} interface, and will allow to cancel the draw
|
812 | 13483 | ppiqueras | * @param scale the scale of the view. Must be between {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
|
813 | 13411 | ppiqueras | * @throws DriverException if fails using some driver.
|
814 | 6878 | cesar | */
|
815 | public void draw(BufferedImage image, Graphics2D g, Cancellable cancel, |
||
816 | double scale) throws DriverException { |
||
817 | if (viewPort.getExtent() == null) { |
||
818 | // System.err.println("viewPort.getExtent() = null");
|
||
819 | return;
|
||
820 | } |
||
821 | System.out.println("Viewport despues: " + viewPort.toString()); |
||
822 | /*
|
||
823 | * if ((viewPort.getImageWidth() <=0) || (viewPort.getImageHeight() <=
|
||
824 | * 0)) { return; }
|
||
825 | */
|
||
826 | |||
827 | prepareDrawing(image, g, scale); |
||
828 | |||
829 | // M?s c?lidad al texto
|
||
830 | RenderingHints renderHints = new RenderingHints( |
||
831 | RenderingHints.KEY_ANTIALIASING,
|
||
832 | RenderingHints.VALUE_ANTIALIAS_ON);
|
||
833 | renderHints.put(RenderingHints.KEY_RENDERING,
|
||
834 | RenderingHints.VALUE_RENDER_QUALITY);
|
||
835 | renderHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||
836 | RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||
837 | g.setRenderingHints(renderHints); |
||
838 | |||
839 | long t1 = System.currentTimeMillis(); |
||
840 | layers.draw(image, g, viewPort, cancel, scale); |
||
841 | |||
842 | LayerDrawEvent beforeTracLayerEvent = new LayerDrawEvent(tracLayer,
|
||
843 | g, viewPort, LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW); |
||
844 | fireLayerDrawingEvent(beforeTracLayerEvent); |
||
845 | tracLayer.draw(image, g, viewPort, cancel, scale); |
||
846 | LayerDrawEvent afterTracLayerEvent = new LayerDrawEvent(tracLayer,
|
||
847 | g, viewPort, LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW); |
||
848 | fireLayerDrawingEvent(afterTracLayerEvent); |
||
849 | 10525 | caballero | |
850 | 10656 | caballero | //layers.setDirty(false);
|
851 | 6878 | cesar | |
852 | long t2 = System.currentTimeMillis(); |
||
853 | System.err.println("Tiempo de dibujado:" + (t2 - t1) + |
||
854 | " mseg. Memoria libre:" + Runtime.getRuntime().freeMemory() / 1024 + " KB"); |
||
855 | /*
|
||
856 | * g.setColor(Color.BLUE); GeneralPath shpR = new
|
||
857 | * GeneralPath(viewPort.getExtent());
|
||
858 | * shpR.transform(viewPort.getAffineTransform()); g.draw(shpR);
|
||
859 | */
|
||
860 | System.gc();
|
||
861 | } |
||
862 | |||
863 | /**
|
||
864 | 13411 | ppiqueras | * <p>Checks out layers that need to be repainted.</p>
|
865 | * <p>If one layer node uses a cache with previous image drawn, but hasn't any, or if it's dirty, then,
|
||
866 | * that layer must be repainted. </p>
|
||
867 | * <p>If one layer node needn't to be repainted, checks out it recursively.</p>
|
||
868 | * <p><i>The cache of "previous image drawn" allows accelerate the repaint process.</i></p>
|
||
869 | *
|
||
870 | * @see #draw(BufferedImage, Graphics2D, Cancellable, double)
|
||
871 | * @see #recursivePrepareDrawing(FLayers, int)
|
||
872 | 6878 | cesar | */
|
873 | private void prepareDrawing(BufferedImage image, Graphics2D g, double scale) { |
||
874 | |||
875 | // Primera pasada: si alguna capa necesita repintarse por debajo
|
||
876 | // de la que tiene la cache, TODAS necesitan
|
||
877 | // ser repintadas.
|
||
878 | boolean bNeedRepaint = false; |
||
879 | boolean bMayExistAceleration = false; |
||
880 | for (int i = 0; i < layers.getLayersCount(); i++) |
||
881 | { |
||
882 | FLayer lyr = layers.getLayer(i); |
||
883 | if (lyr.isCachingDrawnLayers() && (lyr.getCacheImageDrawnLayers() != null)) |
||
884 | { |
||
885 | bMayExistAceleration = true;
|
||
886 | } |
||
887 | else
|
||
888 | { |
||
889 | if (lyr.isDirty())
|
||
890 | bNeedRepaint = true;
|
||
891 | } |
||
892 | } |
||
893 | if (bMayExistAceleration==false) |
||
894 | bNeedRepaint = true;
|
||
895 | if (bNeedRepaint)
|
||
896 | layers.setDirty(true);
|
||
897 | else
|
||
898 | recursivePrepareDrawing(layers, 0);
|
||
899 | } |
||
900 | |||
901 | 13411 | ppiqueras | /**
|
902 | 13508 | ppiqueras | * <p>Invoked by {@linkplain MapContext#recursivePrepareDrawing(FLayers, int)}. Sets all previous layer nodes
|
903 | 13411 | ppiqueras | * in the argument as not dirty, what means that don't need to be repainted.</p>
|
904 | * <p>Each layer node can decide validate or not it's sub-layers according its implementation.</p>
|
||
905 | * <p>This is useful when it's editing, for accelerate the draw, because the layers of a {@link FLayers FLayers} node
|
||
906 | * are painted according its index in the collection, and each one upper the previous.</p>
|
||
907 | *
|
||
908 | * @param layers a node with layers
|
||
909 | * @param index index of the current layer in the internal list of layers
|
||
910 | *
|
||
911 | * @see #recursivePrepareDrawing(FLayers, int)
|
||
912 | * @see #prepareDrawing(BufferedImage, Graphics2D, double)
|
||
913 | */
|
||
914 | 6878 | cesar | private void validatePreviousLayers(FLayers layers, int index) |
915 | { |
||
916 | // TODO: Aqu? quiz?s habr?a que explorar los padres de las capas
|
||
917 | // para marcar y/o asignar la imagen cacheada.
|
||
918 | for (int i = 0; i < index; i++) |
||
919 | { |
||
920 | FLayer lyr = layers.getLayer(i); |
||
921 | lyr.setDirty(false);
|
||
922 | } |
||
923 | // Las de arriba las marcamos como sucias
|
||
924 | // for (int i = index; i < layers.getLayersCount(); i++)
|
||
925 | // {
|
||
926 | // FLayer lyr = layers.getLayer(i);
|
||
927 | // lyr.setDirty(true);
|
||
928 | // }
|
||
929 | } |
||
930 | |||
931 | 13411 | ppiqueras | /**
|
932 | * <p>Checks out recursively, layers that have a cache with an image of previous layers drawn, and if are dirty
|
||
933 | * notify the previous layers that are valid.</p>
|
||
934 | *
|
||
935 | * @param parent node that contains the layers
|
||
936 | * @param indexInParent the least layer index in the <code>parent</code> argument. This allows reduce the time processing
|
||
937 | * if is known that the first layers aren't a collection and will (or won't) be validated
|
||
938 | *
|
||
939 | * @see #prepareDrawing(BufferedImage, Graphics2D, double)
|
||
940 | */
|
||
941 | 6878 | cesar | private void recursivePrepareDrawing(FLayers parent, int indexInParent) |
942 | { |
||
943 | 13411 | ppiqueras | // SUGERENCIA (de Pablo): Intentar evitar que pueda revalidar varias veces las mismas capas, dado
|
944 | // que la imagen de anteriores capas dibujadas contendr? todas las capas previas, y con ello
|
||
945 | // obtener un ligero aumento de velocidad.
|
||
946 | //
|
||
947 | // boolean validated = false;
|
||
948 | // FLayer lyr;
|
||
949 | //
|
||
950 | // for (int i = parent.getLayersCount()-1; i >= indexInParent; i--) {
|
||
951 | // lyr = layers.getLayer(i);
|
||
952 | //
|
||
953 | // if ((!validated) && (lyr.isCachingDrawnLayers()) && (lyr.getCacheImageDrawnLayers() != null))
|
||
954 | // {
|
||
955 | // // les decimos a las anteriores que est?n validadas (not dirty)
|
||
956 | // // para que no se dibujen.
|
||
957 | // if (lyr.isDirty()) {
|
||
958 | // validatePreviousLayers(parent, i);
|
||
959 | // validated = true;
|
||
960 | // }
|
||
961 | // }
|
||
962 | //
|
||
963 | // if (lyr instanceof FLayers)
|
||
964 | // {
|
||
965 | // recursivePrepareDrawing((FLayers)lyr, 0);
|
||
966 | // }
|
||
967 | // }
|
||
968 | |||
969 | 6878 | cesar | for (int i = indexInParent; i < parent.getLayersCount(); i++) |
970 | { |
||
971 | FLayer lyr = layers.getLayer(i); |
||
972 | if (lyr.isCachingDrawnLayers() && (lyr.getCacheImageDrawnLayers() != null)) |
||
973 | { |
||
974 | // les decimos a las anteriores que est?n validadas (not dirty)
|
||
975 | // para que no se dibujen.
|
||
976 | if (lyr.isDirty())
|
||
977 | validatePreviousLayers(parent, i); |
||
978 | } |
||
979 | |||
980 | if (lyr instanceof FLayers) |
||
981 | { |
||
982 | recursivePrepareDrawing((FLayers)lyr, 0);
|
||
983 | } |
||
984 | } |
||
985 | } |
||
986 | |||
987 | 13411 | ppiqueras | /**
|
988 | * <p>Draws only the internal graphic layer using the information of the {@link ViewPort ViewPort} of this map.</p>
|
||
989 | *
|
||
990 | * @param image image used to accelerate the screen draw
|
||
991 | * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
|
||
992 | * @param cancel an object thread that implements the {@link Cancellable Cancellable} interface, and will allow to cancel the draw
|
||
993 | * @param scale value that represents the scale
|
||
994 | * @throws DriverException if fails using some driver.
|
||
995 | *
|
||
996 | * @see GraphicLayer#draw(BufferedImage, Graphics2D, ViewPort, Cancellable, double)
|
||
997 | */
|
||
998 | 6878 | cesar | public void drawGraphics(BufferedImage image, Graphics2D g, |
999 | Cancellable cancel, double scale) throws DriverException { |
||
1000 | if (viewPort == null) |
||
1001 | return;
|
||
1002 | tracLayer.draw(image, g, viewPort, cancel, scale); |
||
1003 | } |
||
1004 | |||
1005 | /**
|
||
1006 | 13411 | ppiqueras | * <p>Like {@linkplain MapContext#draw(BufferedImage, Graphics2D, Cancellable, double)}, but creating
|
1007 | * the task as cancellable.</p>
|
||
1008 | *
|
||
1009 | 13483 | ppiqueras | * @param image buffer used sometimes instead <code>g</code> to accelerate the draw. For example, if two points are as closed that can't be distinguished, draws only one.
|
1010 | 13411 | ppiqueras | * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
|
1011 | * @param scale the scale of the view. Must be between {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
|
||
1012 | *
|
||
1013 | * @throws DriverException if fails using some driver.
|
||
1014 | *
|
||
1015 | * @see #draw(BufferedImage, Graphics2D, Cancellable, double)
|
||
1016 | 6878 | cesar | */
|
1017 | public void draw(BufferedImage image, Graphics2D g, double scale) |
||
1018 | throws DriverException {
|
||
1019 | layers.setDirty(true);
|
||
1020 | draw(image, g, new Cancellable() {
|
||
1021 | 13411 | ppiqueras | /*
|
1022 | 6878 | cesar | * @see com.iver.utiles.swing.threads.Cancellable#isCanceled()
|
1023 | */
|
||
1024 | public boolean isCanceled() { |
||
1025 | return false; |
||
1026 | } |
||
1027 | |||
1028 | 13411 | ppiqueras | /*
|
1029 | * @see com.iver.utiles.swing.threads.Cancellable#setCanceled(boolean)
|
||
1030 | */
|
||
1031 | 6878 | cesar | public void setCanceled(boolean canceled) { |
1032 | // TODO Auto-generated method stub
|
||
1033 | |||
1034 | } |
||
1035 | }, scale); |
||
1036 | } |
||
1037 | |||
1038 | /**
|
||
1039 | 13411 | ppiqueras | * <p>Gets the {@link ViewPort ViewPort} associated to this map.</p>
|
1040 | 6878 | cesar | *
|
1041 | 13411 | ppiqueras | * @return the view port
|
1042 | 13483 | ppiqueras | *
|
1043 | * @see #setViewPort(ViewPort)
|
||
1044 | 6878 | cesar | */
|
1045 | public ViewPort getViewPort() {
|
||
1046 | return viewPort;
|
||
1047 | } |
||
1048 | |||
1049 | /**
|
||
1050 | 13411 | ppiqueras | * <p>Sets a {@link ViewPort ViewPort} with the drawing information
|
1051 | * of this map.</p>
|
||
1052 | * <p>If there was a previous view port, removes its {@link EventBuffer EventBuffer} and
|
||
1053 | 13483 | ppiqueras | * adds the new one.</p>
|
1054 | 6878 | cesar | *
|
1055 | 13411 | ppiqueras | * @param viewPort the viewPort
|
1056 | 13483 | ppiqueras | *
|
1057 | * @see #getViewPort()
|
||
1058 | 6878 | cesar | */
|
1059 | public void setViewPort(ViewPort viewPort) { |
||
1060 | if (this.viewPort != null) { |
||
1061 | this.viewPort.removeViewPortListener(eventBuffer);
|
||
1062 | } |
||
1063 | |||
1064 | this.viewPort = viewPort;
|
||
1065 | 8765 | jjdelcerro | if (viewPort != null) |
1066 | viewPort.addViewPortListener(eventBuffer); |
||
1067 | 6878 | cesar | } |
1068 | 9013 | caballero | |
1069 | 8765 | jjdelcerro | /**
|
1070 | 13411 | ppiqueras | * <p>Sets the given extent to the {@link ViewPort ViewPort} and updates the view with the new zoom.</p>
|
1071 | 8765 | jjdelcerro | *
|
1072 | 13411 | ppiqueras | * @param extent the extent of the new zoom
|
1073 | 8765 | jjdelcerro | */
|
1074 | public void zoomToExtent(Rectangle2D extent) { |
||
1075 | 13019 | cesar | if (extent!=null) |
1076 | getViewPort().setExtent(extent); |
||
1077 | 8765 | jjdelcerro | } |
1078 | 6878 | cesar | |
1079 | /**
|
||
1080 | 13411 | ppiqueras | * <p>Returns the union of all extents of all layers of this map.</p>
|
1081 | 6878 | cesar | *
|
1082 | 13411 | ppiqueras | * @return full extent of layers of this map
|
1083 | * @throws DriverException if fails using a driver.
|
||
1084 | *
|
||
1085 | * @see FLayers#getFullExtent()
|
||
1086 | 6878 | cesar | */
|
1087 | public Rectangle2D getFullExtent() throws DriverException { |
||
1088 | return layers.getFullExtent();
|
||
1089 | } |
||
1090 | |||
1091 | /**
|
||
1092 | 13508 | ppiqueras | * <p>Returns an XML entity with the name of this class as a property, and two children branches:<br>
|
1093 | 13411 | ppiqueras | * <ul>
|
1094 | 13586 | ppiqueras | * <li>XML entity of the internal {@link ViewPort ViewPort}.
|
1095 | * <li>XML entity of the internal {@link FLayers FLayers}.
|
||
1096 | 13411 | ppiqueras | * </ul>
|
1097 | *
|
||
1098 | * @return XMLEntity the XML entity
|
||
1099 | * @throws XMLException if there is any error creating the XML from the map.
|
||
1100 | *
|
||
1101 | 13483 | ppiqueras | * @see #createFromXML(XMLEntity)
|
1102 | * @see #createFromXML03(XMLEntity)
|
||
1103 | 13411 | ppiqueras | * @see ViewPort#getXMLEntity()
|
1104 | * @see FLayers#getXMLEntity()
|
||
1105 | 6878 | cesar | */
|
1106 | public XMLEntity getXMLEntity() throws XMLException { |
||
1107 | XMLEntity xml = new XMLEntity();
|
||
1108 | xml.putProperty("className", this.getClass().getName()); |
||
1109 | xml.addChild(viewPort.getXMLEntity()); |
||
1110 | xml.addChild(layers.getXMLEntity()); |
||
1111 | |||
1112 | return xml;
|
||
1113 | } |
||
1114 | |||
1115 | /**
|
||
1116 | 13411 | ppiqueras | * <p>Creates a new <code>MapContext</code> from an XML entity, with
|
1117 | 13586 | ppiqueras | * the data of the {@link ViewPort ViewPort} and
|
1118 | 13411 | ppiqueras | * {@link FLayers FLayers}.</p>
|
1119 | 6878 | cesar | *
|
1120 | 13411 | ppiqueras | * @param xml an XML entity
|
1121 | 6878 | cesar | *
|
1122 | 13411 | ppiqueras | * @return the new <code>MapContext</code>
|
1123 | 6878 | cesar | *
|
1124 | 13411 | ppiqueras | * @throws XMLException if there is any error creating the map from the XML.
|
1125 | *
|
||
1126 | 13483 | ppiqueras | * @see #getXMLEntity()
|
1127 | * @see #createFromXML(XMLEntity)
|
||
1128 | 13411 | ppiqueras | * @see ViewPort#createFromXML03(XMLEntity)
|
1129 | * @see FLayers#setXMLEntity03(XMLEntity)
|
||
1130 | 6878 | cesar | */
|
1131 | public static MapContext createFromXML03(XMLEntity xml) throws XMLException { |
||
1132 | ViewPort vp = ViewPort.createFromXML03(xml.getChild(0));
|
||
1133 | MapContext fmap = new MapContext(vp);
|
||
1134 | fmap.layers.setXMLEntity03(xml.getChild(1));
|
||
1135 | |||
1136 | return fmap;
|
||
1137 | } |
||
1138 | |||
1139 | /**
|
||
1140 | 13411 | ppiqueras | * <p>Creates a new <code>MapContext</code> from an XML entity, with
|
1141 | * with the data of the {@link ViewPort ViewPort} and
|
||
1142 | * {@link FLayers FLayers}.</p>
|
||
1143 | 6878 | cesar | *
|
1144 | 13411 | ppiqueras | * @param xml an XML entity
|
1145 | 6878 | cesar | *
|
1146 | 13411 | ppiqueras | * @return the new <code>MapContext</code>
|
1147 | 6878 | cesar | *
|
1148 | 13411 | ppiqueras | * @throws XMLException if there is any error creating the map from the XML.
|
1149 | *
|
||
1150 | 13483 | ppiqueras | * @see #getXMLEntity()
|
1151 | * @see #createFromXML03(XMLEntity)
|
||
1152 | 13411 | ppiqueras | * @see ViewPort#createFromXML(XMLEntity)
|
1153 | * @see FLayers#setXMLEntity(XMLEntity)
|
||
1154 | 6878 | cesar | */
|
1155 | public static MapContext createFromXML(XMLEntity xml) throws XMLException { |
||
1156 | ViewPort vp = ViewPort.createFromXML(xml.getChild(0));
|
||
1157 | MapContext fmap = new MapContext(vp);
|
||
1158 | fmap.layers.setXMLEntity(xml.getChild(1));
|
||
1159 | |||
1160 | return fmap;
|
||
1161 | } |
||
1162 | |||
1163 | /**
|
||
1164 | 13411 | ppiqueras | * <p>Adds a listener of atomic events to the internal {@link EventBuffer EventBuffer}.</p>
|
1165 | 6878 | cesar | *
|
1166 | 13411 | ppiqueras | * @param listener the new listener
|
1167 | 6878 | cesar | *
|
1168 | 13411 | ppiqueras | * @return <code>true</code> if has added the listener successfully
|
1169 | *
|
||
1170 | 13483 | ppiqueras | * @see #removeAtomicEventListener(AtomicEventListener)
|
1171 | 13411 | ppiqueras | * @see EventBuffer#addAtomicEventListener(AtomicEventListener)
|
1172 | 6878 | cesar | */
|
1173 | public boolean addAtomicEventListener(AtomicEventListener listener) { |
||
1174 | return eventBuffer.addAtomicEventListener(listener);
|
||
1175 | } |
||
1176 | |||
1177 | /**
|
||
1178 | 13411 | ppiqueras | * <p>Removes a listener of atomic events from the internal {@link EventBuffer EventBuffer}.</p>
|
1179 | 6878 | cesar | *
|
1180 | 13411 | ppiqueras | * @param listener the listener to remove
|
1181 | *
|
||
1182 | * @return <tt>true</tt> if the list contained the specified element
|
||
1183 | *
|
||
1184 | 13483 | ppiqueras | * @see #addAtomicEventListener(AtomicEventListener)
|
1185 | 13411 | ppiqueras | * @see EventBuffer#removeAtomicEventListener(AtomicEventListener)
|
1186 | 6878 | cesar | */
|
1187 | public boolean removeAtomicEventListener(AtomicEventListener listener) { |
||
1188 | return eventBuffer.removeAtomicEventListener(listener);
|
||
1189 | } |
||
1190 | |||
1191 | /**
|
||
1192 | 13411 | ppiqueras | * @see EventBuffer#beginAtomicEvent()
|
1193 | 13483 | ppiqueras | *
|
1194 | * @see #endAtomicEvent()
|
||
1195 | 6878 | cesar | */
|
1196 | public void beginAtomicEvent() { |
||
1197 | eventBuffer.beginAtomicEvent(); |
||
1198 | } |
||
1199 | |||
1200 | /**
|
||
1201 | 13411 | ppiqueras | * @see EventBuffer#endAtomicEvent()
|
1202 | 13483 | ppiqueras | *
|
1203 | * @see #beginAtomicEvent()
|
||
1204 | 6878 | cesar | */
|
1205 | public void endAtomicEvent() { |
||
1206 | eventBuffer.endAtomicEvent(); |
||
1207 | } |
||
1208 | |||
1209 | /**
|
||
1210 | 13411 | ppiqueras | * <p>The class <code>LayerEventListener</code> implements the methods of {@link LayerCollectionListener LayerCollectionListener}
|
1211 | * that handles the "layer added" or "layer removed" events in a map.</p>
|
||
1212 | * <p>Is designed as a listener for all layers in a {@link MapContext MapContext}.</p>
|
||
1213 | 6878 | cesar | *
|
1214 | * @author Fernando Gonz?lez Cort?s
|
||
1215 | */
|
||
1216 | public class LayerEventListener implements LayerCollectionListener { |
||
1217 | 13411 | ppiqueras | /*
|
1218 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdded(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
|
1219 | */
|
||
1220 | public void layerAdded(LayerCollectionEvent e) { |
||
1221 | // Si es la primera capa, fijamos su extent al ViewPort
|
||
1222 | // if (getLayers().getLayersCount() == 1) {
|
||
1223 | if (getViewPort().getExtent() == null) { |
||
1224 | FLayer lyr = e.getAffectedLayer(); |
||
1225 | |||
1226 | try {
|
||
1227 | getViewPort().setExtent(lyr.getFullExtent()); |
||
1228 | } catch (DriverException e1) {
|
||
1229 | } |
||
1230 | } |
||
1231 | |||
1232 | // Registramos al FMap como listener del legend de las capas
|
||
1233 | FLayer lyr = e.getAffectedLayer(); |
||
1234 | 9473 | fdiaz | selectionListener(lyr); |
1235 | } |
||
1236 | 6878 | cesar | |
1237 | 13411 | ppiqueras | /**
|
1238 | * <p>Registers an event buffer as a listener for all layers as argument.</p>
|
||
1239 | *
|
||
1240 | * <p>Each {@link FLayer FLayer} of this map must have an event buffer for all kind
|
||
1241 | * of specific listeners of that layer. This method distinguish between {@link Classifiable Classifiable},
|
||
1242 | * {@link AlphanumericData AlphanumericData}, and {@link FLayers FLayers} layers, and for each one,
|
||
1243 | * registers, for their specific listeners, the <code>eventBuffer</code> as a listener.</p>
|
||
1244 | *
|
||
1245 | * @param the layer or layers
|
||
1246 | */
|
||
1247 | 9473 | fdiaz | private void selectionListener(FLayer lyr){ |
1248 | 6878 | cesar | lyr.addLayerListener(eventBuffer); |
1249 | |||
1250 | if (lyr instanceof Classifiable) { |
||
1251 | Classifiable c = (Classifiable) lyr; |
||
1252 | c.addLegendListener(eventBuffer); |
||
1253 | } |
||
1254 | |||
1255 | if (lyr instanceof AlphanumericData) { |
||
1256 | Selectable s=null;
|
||
1257 | try {
|
||
1258 | s = ((AlphanumericData) lyr).getRecordset(); |
||
1259 | if (s!=null) { |
||
1260 | s.addSelectionListener(eventBuffer); |
||
1261 | } |
||
1262 | } catch (DriverException e1) {
|
||
1263 | // TODO Auto-generated catch block
|
||
1264 | e1.printStackTrace(); |
||
1265 | } |
||
1266 | |||
1267 | } |
||
1268 | 9473 | fdiaz | if (lyr instanceof FLayers){ |
1269 | FLayers lyrs=(FLayers)lyr; |
||
1270 | for(int i=0;i<lyrs.getLayersCount();i++){ |
||
1271 | selectionListener(lyrs.getLayer(i)); |
||
1272 | } |
||
1273 | } |
||
1274 | 13411 | ppiqueras | } |
1275 | 9473 | fdiaz | |
1276 | 13411 | ppiqueras | /*
|
1277 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoved(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
|
1278 | */
|
||
1279 | public void layerMoved(LayerPositionEvent e) { |
||
1280 | } |
||
1281 | |||
1282 | 13411 | ppiqueras | /*
|
1283 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoved(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
|
1284 | */
|
||
1285 | public void layerRemoved(LayerCollectionEvent e) { |
||
1286 | FLayer lyr = e.getAffectedLayer(); |
||
1287 | |||
1288 | lyr.removeLayerListener(eventBuffer); |
||
1289 | |||
1290 | if (lyr instanceof Classifiable) { |
||
1291 | Classifiable c = (Classifiable) lyr; |
||
1292 | c.removeLegendListener(eventBuffer); |
||
1293 | } |
||
1294 | |||
1295 | if (lyr instanceof Selectable) { |
||
1296 | Selectable s = (Selectable) lyr; |
||
1297 | s.addSelectionListener(eventBuffer); |
||
1298 | } |
||
1299 | } |
||
1300 | |||
1301 | 13411 | ppiqueras | /*
|
1302 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdding(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
|
1303 | */
|
||
1304 | public void layerAdding(LayerCollectionEvent e) |
||
1305 | throws CancelationException {
|
||
1306 | } |
||
1307 | |||
1308 | 13411 | ppiqueras | /*
|
1309 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoving(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
|
1310 | */
|
||
1311 | public void layerMoving(LayerPositionEvent e) |
||
1312 | throws CancelationException {
|
||
1313 | } |
||
1314 | |||
1315 | 13411 | ppiqueras | /*
|
1316 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoving(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
|
1317 | */
|
||
1318 | public void layerRemoving(LayerCollectionEvent e) |
||
1319 | throws CancelationException {
|
||
1320 | } |
||
1321 | |||
1322 | 13411 | ppiqueras | /*
|
1323 | 6878 | cesar | * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#visibilityChanged(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
|
1324 | */
|
||
1325 | public void visibilityChanged(LayerCollectionEvent e) |
||
1326 | throws CancelationException {
|
||
1327 | } |
||
1328 | } |
||
1329 | |||
1330 | 13411 | ppiqueras | /**
|
1331 | * <p>Adds the {@link LayerEventListener LayerEventListener} of this map to the
|
||
1332 | * collection of layers argument.</p>
|
||
1333 | *
|
||
1334 | * @param a collection of layers
|
||
1335 | */
|
||
1336 | 6878 | cesar | public void addAsCollectionListener(FLayers layers2) { |
1337 | layers2.addLayerCollectionListener(layerEventListener); |
||
1338 | } |
||
1339 | |||
1340 | 13411 | ppiqueras | /**
|
1341 | * <p>Returns the internal {@link GraphicLayer GraphicLayer}.</p>
|
||
1342 | *
|
||
1343 | * @return the graphic layer of this map
|
||
1344 | 13483 | ppiqueras | *
|
1345 | * @see #setGraphicsLayer(GraphicLayer)
|
||
1346 | 13411 | ppiqueras | */
|
1347 | 6878 | cesar | public GraphicLayer getGraphicsLayer() {
|
1348 | return tracLayer;
|
||
1349 | } |
||
1350 | |||
1351 | /**
|
||
1352 | 13411 | ppiqueras | * <p>Sets a new {@link GraphicLayer GraphicLayer} to this map.</p>
|
1353 | *
|
||
1354 | * @param graphicLayer the new graphic layer
|
||
1355 | 13483 | ppiqueras | *
|
1356 | * @see #getGraphicsLayer()
|
||
1357 | 6878 | cesar | */
|
1358 | public void setGraphicsLayer(GraphicLayer graphicLayer) { |
||
1359 | tracLayer = graphicLayer; |
||
1360 | } |
||
1361 | |||
1362 | 13411 | ppiqueras | /**
|
1363 | * <p>Indicates whether some other object is "equal to" this map.</p>
|
||
1364 | * <p>Returns <code>true</code> if success on this options:
|
||
1365 | * <ol>
|
||
1366 | * <li>Both objects are equal according to {@linkplain Object#equals(Object)}.
|
||
1367 | * <li>Both maps have the same layers.
|
||
1368 | * <li>Both maps have the same number of layers and with the same name.
|
||
1369 | * </ol>
|
||
1370 | * </p>
|
||
1371 | *
|
||
1372 | * @param obj the reference object with which to compare.
|
||
1373 | * @return <code>true</code> if this object is the same as the <code>arg0</code> argument; <code>false</code> otherwise.
|
||
1374 | *
|
||
1375 | * @see Object#equals(Object)
|
||
1376 | */
|
||
1377 | 6878 | cesar | public boolean equals(Object arg0) { |
1378 | MapContext map = (MapContext) arg0; |
||
1379 | if (super.equals(arg0)) |
||
1380 | return true; |
||
1381 | if (getLayers() == map.getLayers())
|
||
1382 | return true; |
||
1383 | boolean isEqual = true; |
||
1384 | if (map.getLayers().getLayersCount() == getLayers().getLayersCount()) {
|
||
1385 | for (int i = 0; i < getLayers().getLayersCount(); i++) { |
||
1386 | |||
1387 | if (!getLayers().getLayer(i).getName().equals(
|
||
1388 | map.getLayers().getLayer(i).getName())) { |
||
1389 | isEqual = false;
|
||
1390 | } |
||
1391 | |||
1392 | } |
||
1393 | } else {
|
||
1394 | isEqual = false;
|
||
1395 | } |
||
1396 | return isEqual;
|
||
1397 | } |
||
1398 | |||
1399 | 13411 | ppiqueras | /**
|
1400 | * <p>Registers the message of an error associated to this map.</p>
|
||
1401 | *
|
||
1402 | * @param stringProperty the error message
|
||
1403 | *
|
||
1404 | * @see #getLayersError()
|
||
1405 | * @see #clearErrors()
|
||
1406 | */
|
||
1407 | 6878 | cesar | public void addLayerError(String stringProperty) { |
1408 | layersError.add(stringProperty); |
||
1409 | } |
||
1410 | |||
1411 | 13411 | ppiqueras | /**
|
1412 | * <p>Gets the list with all errors messages registered to this map.</p>
|
||
1413 | *
|
||
1414 | * @return the list of errors registered to this map
|
||
1415 | *
|
||
1416 | * @see #addLayerError(String)
|
||
1417 | * @see #clearErrors()
|
||
1418 | */
|
||
1419 | 6878 | cesar | public ArrayList getLayersError() { |
1420 | return layersError;
|
||
1421 | } |
||
1422 | |||
1423 | 13411 | ppiqueras | /**
|
1424 | * <p>Removes all error messages associated to this map.</p>
|
||
1425 | *
|
||
1426 | * @see #addLayerError(String)
|
||
1427 | * @see #getLayersError()
|
||
1428 | */
|
||
1429 | 6878 | cesar | public void clearErrors() { |
1430 | layersError.clear(); |
||
1431 | } |
||
1432 | 8765 | jjdelcerro | |
1433 | 13411 | ppiqueras | /**
|
1434 | * <p>Removes from this map, all caching images of drawn layers, registered.</p>
|
||
1435 | *
|
||
1436 | 13483 | ppiqueras | * @see #clearCachingImageDrawnLayers(FLayers)
|
1437 | 13411 | ppiqueras | */
|
1438 | 7366 | jmvivo | public void clearAllCachingImageDrawnLayers() { |
1439 | clearCachingImageDrawnLayers(this.layers);
|
||
1440 | 13411 | ppiqueras | } |
1441 | |||
1442 | /**
|
||
1443 | * <p>Removes from the layer collection argument, all caching images of drawn layers, registered.</p>
|
||
1444 | *
|
||
1445 | * @param layers a layer collection
|
||
1446 | 13483 | ppiqueras | *
|
1447 | * @see #clearAllCachingImageDrawnLayers()
|
||
1448 | 13411 | ppiqueras | */
|
1449 | 7366 | jmvivo | private void clearCachingImageDrawnLayers(FLayers layers){ |
1450 | int i;
|
||
1451 | FLayer layer; |
||
1452 | for (i=0;i< layers.getLayersCount();i++){ |
||
1453 | layer = layers.getLayer(i); |
||
1454 | if (layer instanceof FLayers) { |
||
1455 | clearCachingImageDrawnLayers((FLayers)layer); |
||
1456 | } else {
|
||
1457 | layer.setCacheImageDrawnLayers(null);
|
||
1458 | } |
||
1459 | 8765 | jjdelcerro | } |
1460 | 7366 | jmvivo | } |
1461 | 8765 | jjdelcerro | |
1462 | 13411 | ppiqueras | /**
|
1463 | 13508 | ppiqueras | * <p>Applies for a refresh everything what depends on this map: TOC, <code>MapControl</code>,
|
1464 | * <code>FFrameView</code>, ... To do this, it produces an event of layer order change.</p>
|
||
1465 | 13411 | ppiqueras | */
|
1466 | 8765 | jjdelcerro | public void redraw() { |
1467 | // truco
|
||
1468 | if (getLayers().getLayersCount() > 0) |
||
1469 | getLayers().moveTo(0,0); |
||
1470 | } |
||
1471 | 6878 | cesar | } |