Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapContext.java @ 37949

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