Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / mapcontext / MapContext.java @ 21102

History | View | Annotate | Download (53.7 KB)

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