Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / FMap.java @ 3772

History | View | Annotate | Download (22.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.RenderingHints;
45
import java.awt.Toolkit;
46
import java.awt.geom.Point2D;
47
import java.awt.geom.Rectangle2D;
48
import java.awt.image.BufferedImage;
49
import java.util.ArrayList;
50

    
51
import org.cresques.cts.ICoordTrans;
52
import org.cresques.cts.IProjection;
53
import org.cresques.geo.Projected;
54

    
55
import com.iver.cit.gvsig.fmap.core.IGeometry;
56
import com.iver.cit.gvsig.fmap.layers.CancelationException;
57
import com.iver.cit.gvsig.fmap.layers.FLayer;
58
import com.iver.cit.gvsig.fmap.layers.FLayers;
59
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
60
import com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent;
61
import com.iver.cit.gvsig.fmap.layers.LayerCollectionListener;
62
import com.iver.cit.gvsig.fmap.layers.LayerDrawEvent;
63
import com.iver.cit.gvsig.fmap.layers.LayerDrawingListener;
64
import com.iver.cit.gvsig.fmap.layers.LayerPositionEvent;
65
import com.iver.cit.gvsig.fmap.layers.LegendListener;
66
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
67
import com.iver.cit.gvsig.fmap.layers.XMLException;
68
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
69
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
70
import com.iver.cit.gvsig.fmap.operations.Cancellable;
71
import com.iver.cit.gvsig.fmap.operations.selection.Record;
72
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
73
import com.iver.cit.gvsig.fmap.operations.strategies.SelectedZoomVisitor;
74
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
75
import com.iver.cit.gvsig.fmap.rendering.styling.FStyle2D;
76
import com.iver.utiles.XMLEntity;
77

    
78
/**
79
 * Modelo del mapa.
80
 * 
81
 * @author Fernando Gonz?lez Cort?s
82
 */
83
public class FMap implements Projected {
84
        public static final double[] CHANGEM = { 1000, 1, 0.01, 0.001, 1609.344,
85
                        0.9144, 0.3048, 0.0254 };
86

    
87
        public static final double[] CHANGE = { 100000, 100, 1, 0.1, 160934.4,
88
                        91.44, 30.48, 2.54 };
89

    
90
        public static final int EQUALS = 0;
91

    
92
        public static final int DISJOINT = 1;
93

    
94
        public static final int INTERSECTS = 2;
95

    
96
        public static final int TOUCHES = 3;
97

    
98
        public static final int CROSSES = 4;
99

    
100
        public static final int WITHIN = 5;
101

    
102
        public static final int CONTAINS = 6;
103

    
104
        public static final int OVERLAPS = 7;
105

    
106
        private FLayers layers = new FLayers(this, null);
107

    
108
        private GraphicLayer tracLayer = new GraphicLayer();
109

    
110
        private ViewPort viewPort;
111

    
112
        // private ArrayList invalidationListeners = new ArrayList();
113
        private ArrayList legendListeners = new ArrayList();
114

    
115
        private ArrayList layerDrawingListeners = new ArrayList();
116

    
117
        private EventBuffer eventBuffer = new EventBuffer();
118

    
119
        private LayerEventListener layerEventListener = null;
120

    
121
        private ArrayList layersError = new ArrayList();
122

    
123
        private ArrayList errorListeners = new ArrayList();
124

    
125
        // public static ResourceBundle myResourceBundle =
126
        // ResourceBundle.getBundle("FMap");
127

    
128
        /**
129
         * Crea un nuevo FMap.
130
         * 
131
         * @param vp
132
         *            ViewPort.
133
         */
134
        public FMap(ViewPort vp) {
135
                this.viewPort = vp;
136
                layerEventListener = new LayerEventListener();
137
                layers.addLayerCollectionListener(layerEventListener);
138
                layers.addLayerCollectionListener(eventBuffer);
139

    
140
                if (viewPort != null) {
141
                        viewPort.addViewPortListener(eventBuffer);
142
                }
143
        }
144

    
145
        /**
146
         * A?ade un LegendListener.
147
         * 
148
         * @param listener
149
         *            LegendListener a a?adir.
150
         */
151
        public void addLayerListener(LegendListener listener) {
152
                legendListeners.add(listener);
153
        }
154

    
155
        public void addLayerDrawingListener(LayerDrawingListener listener) {
156
                layerDrawingListeners.add(listener);
157
        }
158

    
159
        public void removeLayerDrawListener(LayerDrawingListener listener) {
160
                layerDrawingListeners.remove(listener);
161
        }
162

    
163
        public void addErrorListener(ErrorListener listener) {
164
                errorListeners.add(listener);
165
        }
166

    
167
        public void removeErrorListener(LegendListener listener) {
168
                legendListeners.remove(listener);
169
        }
170

    
171
        /**
172
         * M?todo ejecutado cuando hay un cambio de leyenda que se quiera reflejar.
173
         * 
174
         * @param e
175
         *            LegendChangedEvent.
176
         */
177
        public synchronized void callLegendChanged() {
178
                for (int i = 0; i < legendListeners.size(); i++) {
179
                        ((LegendListener) legendListeners.get(i)).legendChanged(null);
180
                }
181
                // getLayers().moveTo(0,0);
182
        }
183

    
184
        public synchronized void fireLayerDrawingEvent(LayerDrawEvent e) {
185
                for (int i = 0; i < layerDrawingListeners.size(); i++)
186
                {
187
                        LayerDrawingListener listener = (LayerDrawingListener) layerDrawingListeners.get(i);
188
                        switch (e.getEventType())
189
                        {
190
                                case LayerDrawEvent.LAYER_BEFORE_DRAW:
191
                                        listener.beforeLayerDraw(e);
192
                                        break;
193
                                case LayerDrawEvent.LAYER_AFTER_DRAW:
194
                                        listener.afterLayerDraw(e);
195
                                        break;
196
                                case LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW:
197
                                        listener.beforeGraphicLayerDraw(e);
198
                                        break;
199
                                case LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW:
200
                                        listener.afterLayerGraphicDraw(e);
201
                                        break;                                        
202
                        }
203
                }
204
                // getLayers().moveTo(0,0);
205
        }
206

    
207
        public synchronized void callNewErrorEvent(ErrorEvent e) {
208
                for (int i = 0; i < errorListeners.size(); i++) {
209
                        ((ErrorListener) errorListeners.get(i)).errorThrown(e);
210
                }
211
                // getLayers().moveTo(0,0);
212
        }
213

    
214
        /**
215
         * Borra un LegendListener.
216
         * 
217
         * @param listener
218
         *            LegendListener a borrar.
219
         */
220
        public void removeLayerListener(LegendListener listener) {
221
                legendListeners.remove(listener);
222
        }
223

    
224
        /**
225
         * Devuelve las capas que contiene el mapa.
226
         * 
227
         * @return Capas.
228
         */
229
        public FLayers getLayers() {
230
                return layers;
231
        }
232

    
233
        /**
234
         * Dibuja en la imagen que se pasa como par?metro el contenido de las capas
235
         * visibles del mapa y teniendo en cuenta los datos del ViewPort contenido
236
         * en este FMap
237
         * 
238
         * @param b
239
         *            Imagen.
240
         */
241
        public void drawLabels(BufferedImage b) {
242
        }
243

    
244
        /**
245
         * M?todo de conveniencia que se usa provisionalmente para solicitar un
246
         * refresco de todo lo que dependa del FMap (MapContext). Esto provocar? un
247
         * evento de cambio de orden de capas que obligar? a redibujar todo lo que
248
         * depende de FMap (TOC, MapControl, FFrameView, etc).
249
         */
250
        public void invalidate() {
251
                getLayers().moveTo(0, 0);
252
        }
253

    
254
        /**
255
         * Imprime el las capas que contiene el FMap sobre el Graphics2D que se pasa
256
         * como par?metro, normalmente es el Graphics de la impresora.
257
         * 
258
         * @param g
259
         *            Graphics2D
260
         * 
261
         * @throws DriverException
262
         */
263
        public void print(Graphics2D g, double scale) throws DriverException {
264
                RenderingHints renderHints = new RenderingHints(
265
                                RenderingHints.KEY_ANTIALIASING,
266
                                RenderingHints.VALUE_ANTIALIAS_ON);
267
                renderHints.put(RenderingHints.KEY_RENDERING,
268
                                RenderingHints.VALUE_RENDER_QUALITY);
269
                g.setRenderingHints(renderHints);
270

    
271
                Cancellable cancel = new Cancellable() {
272
                        public boolean isCanceled() {
273
                                return false;
274
                        }
275
                };
276
                layers.print(g, viewPort, cancel, scale);
277
                tracLayer.draw(null, g, viewPort, cancel, scale);
278
        }
279

    
280
        /**
281
         * Crea un nuevo FMap con la informaci?n del ViewPort que se pasa como
282
         * par?metro.
283
         * 
284
         * @param vp
285
         *            ViewPort.
286
         * 
287
         * @return FMap nuevo.
288
         */
289
        public FMap createNewFMap(ViewPort vp) {
290
                FMap ret = new FMap(vp);
291
                ret.layers = this.layers;
292

    
293
                return ret;
294
        }
295

    
296
        /**
297
         * Crea un nuevo FMap totalmente desligado, se replican las capas y el
298
         * ViewPort
299
         * 
300
         * @return FMap clonado.
301
         * 
302
         * @throws XMLException
303
         */
304
        public FMap cloneFMap() throws XMLException {
305
                return createFromXML(getXMLEntity());
306
        }
307

    
308
        /**
309
         * A?ade la capa que se pasa como par?metro al nodo que se pasa como
310
         * parametro y lanza ProjectionMismatchException si no est?n todas las capas
311
         * de este FMap en la misma proyecci?n. Lanza un ChildNotAllowedException si
312
         * la capa no es un FLayers y no permite hijos
313
         * 
314
         * @param vectorial
315
         *            DOCUMENT ME!
316
         */
317

    
318
        /*
319
         * public void addLayer(LayerPath parent, FLayer layer) throws
320
         * ProjectionMismatchException, ChildrenNotAllowedException {
321
         * layers.addLayer(parent, layer); } public void removeLayer(LayerPath
322
         * parent)throws ChildrenNotAllowedException{ layers.removeLayer(parent); }
323
         */
324

    
325
        /**
326
         * A?ade una capa al grupo de capas que se sit?a por encima de todas las
327
         * otras capas
328
         * 
329
         * @param vectorial
330
         *            FLayer.
331
         */
332
        public void addToTrackLayer(FLayer vectorial) {
333
        }
334

    
335
        /**
336
         * Devuelve la escala de la vista en pantalla.
337
         * 
338
         * @return escala de la vista.
339
         */
340
        public long getScaleView() {
341
                // TODO falta implementar un di?logo para poder especificar el usuario
342
                // los pixels exactos de su pantalla.
343
                Toolkit kit = Toolkit.getDefaultToolkit();
344
                double dpi = kit.getScreenResolution();
345
                IProjection proj = viewPort.getProjection();
346

    
347
                if (viewPort.getImageSize() == null)
348
                        return -1;
349

    
350
                double w = ((viewPort.getImageSize().getWidth() / dpi) * 2.54);
351

    
352
                if (viewPort.getAdjustedExtent() == null) {
353
                        return 0;
354
                }
355

    
356
                if (proj == null) {
357
                        return (long) (viewPort.getAdjustedExtent().getWidth() / w * CHANGE[getViewPort()
358
                                        .getMapUnits()]);
359
                }
360

    
361
                return (long) proj.getScale(viewPort.getAdjustedExtent().getMinX(),
362
                                viewPort.getAdjustedExtent().getMaxX(), viewPort.getImageSize()
363
                                                .getWidth(), dpi);
364
        }
365

    
366
        /**
367
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#setVectorial(com.iver.cit.gvsig.fmap.VectorialAdapter)
368
         */
369
        public void setVectorial(VectorialAdapter v) {
370
        }
371

    
372
        /**
373
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#process(com.iver.cit.gvsig.fmap.FeatureSelectorVisitor)
374
         */
375
        public void process(FeatureVisitor visitor) {
376
        }
377

    
378
        /**
379
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#processSelected(com.iver.cit.gvsig.fmap.FeatureVisitor)
380
         */
381
        public void processSelected(FeatureVisitor visitor) {
382
        }
383

    
384
        /**
385
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#select(com.iver.cit.gvsig.fmap.FeatureSelectorVisitor,
386
         *      VectorialSubSet)
387
         */
388
        public void select(FeatureVisitor visitor) {
389
        }
390

    
391
        /**
392
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#selectFromSelection()
393
         */
394
        public void selectFromSelection() {
395
        }
396

    
397
        /**
398
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#createIndex()
399
         */
400
        public void createIndex() {
401
        }
402

    
403
        /**
404
         * @see org.cresques.geo.Projected#getProjection()
405
         */
406
        public IProjection getProjection() {
407
                return getViewPort().getProjection();
408
        }
409

    
410
        /**
411
         * Inserta la proyecci?n.
412
         * 
413
         * @param proj
414
         *            Proyecci?n.
415
         */
416
        public void setProjection(IProjection proj) {
417
                getViewPort().setProjection(proj);
418
        }
419

    
420
        /**
421
         * @see org.cresques.geo.Projected#reProject(org.cresques.cts.ICoordTrans)
422
         */
423
        public void reProject(ICoordTrans arg0) {
424
                // TODO implementar reprojecci?n (lo que sea eso)
425
        }
426

    
427
        /**
428
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#selectByPoint(java.awt.geom.Point2D,
429
         *      double)
430
         */
431
        /*
432
         * public void selectByPoint(Point2D p, double tolerance) throws
433
         * DriverException { Point2D mapPoint = viewPort.toMapPoint((int) p.getX(),
434
         * (int) p.getY()); SelectByPointVisitor visitor = new
435
         * SelectByPointVisitor(); visitor.setQueriedPoint(mapPoint);
436
         * visitor.setTolerance(getViewPort().toMapDistance(3));
437
         * 
438
         * try { layers.process(visitor); } catch (VisitException e) { throw new
439
         * RuntimeException("No se espera que SelectByPointVisitor lance esta
440
         * excepci?n", e); } }
441
         */
442

    
443
        /**
444
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#selectByRect(java.awt.geom.Rectangle2D)
445
         */
446
        /*
447
         * public void selectByRect(Rectangle2D rect) throws DriverException {
448
         * FLayer[] actives = layers.getActives(); for (int i=0; i < actives.length;
449
         * i++) { if (actives[i] instanceof FLyrVect) { FLyrVect lyrVect =
450
         * (FLyrVect) actives[i]; FBitSet oldBitSet = lyrVect.getSelection();
451
         * FBitSet newBitSet = lyrVect.queryByRect(rect); newBitSet.xor(oldBitSet);
452
         * lyrVect.setSelection(newBitSet); } }
453
         *  }
454
         */
455

    
456
        /**
457
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#selectByShape(com.iver.cit.gvsig.fmap.fshape.IGeometry,
458
         *      int)
459
         */
460
        public void selectByShape(IGeometry g, int relationship) {
461
        }
462

    
463
        /**
464
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByPoint(Point2D,
465
         *      double)
466
         */
467
        public Record[] queryByPoint(Point2D p, double tolerance) {
468
                return null;
469
        }
470

    
471
        /**
472
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByRect(java.awt.geom.Rectangle2D)
473
         */
474
        public Record[] queryByRect(Rectangle2D rect) {
475
                return null;
476
        }
477

    
478
        /**
479
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#queryByShape(com.iver.cit.gvsig.fmap.fshape.IGeometry,
480
         *      int)
481
         */
482
        public Record[] queryByShape(IGeometry g, int relationship) {
483
                return null;
484
        }
485

    
486
        /**
487
         * @see com.iver.cit.gvsig.fmap.operations.strategies.Strategy#getSelectionBounds()
488
         */
489
        public Rectangle2D getSelectionBounds() {
490
                SelectedZoomVisitor visitor = new SelectedZoomVisitor();
491

    
492
                try {
493
                        layers.process(visitor);
494
                } catch (DriverException e1) {
495
                        throw new RuntimeException(
496
                                        "No se espera que SelectByPointVisitor lance esta excepci?n",
497
                                        e1);
498
                } catch (VisitException e) {
499
                        throw new RuntimeException(
500
                                        "No se espera que SelectByPointVisitor lance esta excepci?n",
501
                                        e);
502
                }
503

    
504
                return visitor.getSelectBound();
505
        }
506

    
507
        /**
508
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
509
         *      java.awt.Graphics2D, FStyle2D)
510
         */
511
        public void draw(BufferedImage image, Graphics2D g, Cancellable cancel,
512
                        double scale) throws DriverException {
513
                if (viewPort.getExtent() == null) {
514
                        // System.err.println("viewPort.getExtent() = null");
515
                        return;
516
                }
517

    
518
                System.out.println("Viewport despues: " + viewPort.toString());
519
                /*
520
                 * if ((viewPort.getImageWidth() <=0) || (viewPort.getImageHeight() <=
521
                 * 0)) { return; }
522
                 */
523
                // M?s c?lidad al texto
524
                RenderingHints renderHints = new RenderingHints(
525
                                RenderingHints.KEY_ANTIALIASING,
526
                                RenderingHints.VALUE_ANTIALIAS_ON);
527
                renderHints.put(RenderingHints.KEY_RENDERING,
528
                                RenderingHints.VALUE_RENDER_QUALITY);
529
                renderHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
530
                                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
531
                g.setRenderingHints(renderHints);
532

    
533
                long t1 = System.currentTimeMillis();
534
                layers.draw(image, g, viewPort, cancel, scale);
535

    
536
                LayerDrawEvent beforeTracLayerEvent = new LayerDrawEvent(tracLayer,
537
                                g, viewPort, LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW);
538
                fireLayerDrawingEvent(beforeTracLayerEvent);
539
                tracLayer.draw(image, g, viewPort, cancel, scale);
540
                LayerDrawEvent afterTracLayerEvent = new LayerDrawEvent(tracLayer,
541
                                g, viewPort, LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW);
542
                fireLayerDrawingEvent(afterTracLayerEvent);
543
                
544
                long t2 = System.currentTimeMillis();
545
                System.err.println("Tiempo de dibujado:" + (t2 - t1) + " mseg.");
546
                /*
547
                 * g.setColor(Color.BLUE); GeneralPath shpR = new
548
                 * GeneralPath(viewPort.getExtent());
549
                 * shpR.transform(viewPort.getAffineTransform()); g.draw(shpR);
550
                 */
551
                System.gc();
552
        }
553

    
554
        public void drawGraphics(BufferedImage image, Graphics2D g,
555
                        Cancellable cancel, double scale) throws DriverException {
556
                if (viewPort == null)
557
                        return;
558
                tracLayer.draw(image, g, viewPort, cancel, scale);
559
        }
560

    
561
        /**
562
         * @see com.iver.cit.gvsig.fmap.operations.LayerOperations#draw(java.awt.image.BufferedImage,
563
         *      java.awt.Graphics2D, FStyle2D)
564
         */
565
        public void draw(BufferedImage image, Graphics2D g, double scale)
566
                        throws DriverException {
567
                draw(image, g, new Cancellable() {
568
                        /**
569
                         * @see com.iver.cit.gvsig.fmap.operations.Cancellable#isCanceled()
570
                         */
571
                        public boolean isCanceled() {
572
                                return false;
573
                        }
574
                }, scale);
575
        }
576

    
577
        /**
578
         * Devuelve el ViewPort.
579
         * 
580
         * @return Returns the viewPort.
581
         */
582
        public ViewPort getViewPort() {
583
                return viewPort;
584
        }
585

    
586
        /**
587
         * Inserta un ViewPort.
588
         * 
589
         * @param viewPort
590
         *            The viewPort to set.
591
         */
592
        public void setViewPort(ViewPort viewPort) {
593
                if (this.viewPort != null) {
594
                        this.viewPort.removeViewPortListener(eventBuffer);
595
                }
596

    
597
                this.viewPort = viewPort;
598
                viewPort.addViewPortListener(eventBuffer);
599
        }
600

    
601
        /**
602
         * M?todo de conveniencia. Recorre las capas y te da el fullExtent
603
         * 
604
         * @return fullExtent de todas las capas.
605
         * 
606
         * @throws DriverException
607
         */
608
        public Rectangle2D getFullExtent() throws DriverException {
609
                return layers.getFullExtent();
610
        }
611

    
612
        /**
613
         * Devuelve el XMLEntity.
614
         * 
615
         * @return XMLEntity.
616
         * @throws XMLException
617
         */
618
        public XMLEntity getXMLEntity() throws XMLException {
619
                XMLEntity xml = new XMLEntity();
620
                xml.putProperty("className", this.getClass().getName());
621
                xml.addChild(viewPort.getXMLEntity());
622
                xml.addChild(layers.getXMLEntity());
623

    
624
                return xml;
625
        }
626

    
627
        /**
628
         * Crea un nuevo FMAp a partir del XMLEntity.
629
         * 
630
         * @param xml
631
         *            XMLEntity
632
         * 
633
         * @return Nuevo FMap.
634
         * 
635
         * @throws XMLException
636
         */
637
        public static FMap createFromXML03(XMLEntity xml) throws XMLException {
638
                ViewPort vp = ViewPort.createFromXML03(xml.getChild(0));
639
                FMap fmap = new FMap(vp);
640
                fmap.layers.setXMLEntity03(xml.getChild(1));
641

    
642
                return fmap;
643
        }
644

    
645
        /**
646
         * Crea un nuevo FMAp a partir del XMLEntity.
647
         * 
648
         * @param xml
649
         *            XMLEntity
650
         * 
651
         * @return Nuevo FMap.
652
         * 
653
         * @throws XMLException
654
         */
655
        public static FMap createFromXML(XMLEntity xml) throws XMLException {
656
                ViewPort vp = ViewPort.createFromXML(xml.getChild(0));
657
                FMap fmap = new FMap(vp);
658
                fmap.layers.setXMLEntity(xml.getChild(1));
659

    
660
                return fmap;
661
        }
662

    
663
        /**
664
         * A?ade un AtomicEventListener.
665
         * 
666
         * @param listener
667
         *            AtomicEventListener.
668
         * 
669
         * @return True si se ha a?adido correctamente.
670
         */
671
        public boolean addAtomicEventListener(AtomicEventListener listener) {
672
                return eventBuffer.addAtomicEventListener(listener);
673
        }
674

    
675
        /**
676
         * Borra un AtomicEventListener de la lista de listeners.
677
         * 
678
         * @param listener
679
         *            AtomicEventListener a borrar.
680
         * 
681
         * @return True si se ha borrado correctamente.
682
         */
683
        public boolean removeAtomicEventListener(AtomicEventListener listener) {
684
                return eventBuffer.removeAtomicEventListener(listener);
685
        }
686

    
687
        /**
688
         * Inicializa los AtomicEvent.
689
         */
690
        public void beginAtomicEvent() {
691
                eventBuffer.beginAtomicEvent();
692
        }
693

    
694
        /**
695
         * Finaliza los AtomicEvent.
696
         */
697
        public void endAtomicEvent() {
698
                eventBuffer.endAtomicEvent();
699
        }
700

    
701
        /**
702
         * Evento Layer.
703
         * 
704
         * @author Fernando Gonz?lez Cort?s
705
         */
706
        public class LayerEventListener implements LayerCollectionListener {
707
                /**
708
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdded(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
709
                 */
710
                public void layerAdded(LayerCollectionEvent e) {
711
                        // Si es la primera capa, fijamos su extent al ViewPort
712
                        // if (getLayers().getLayersCount() == 1) {
713
                        if (getViewPort().getExtent() == null) {
714
                                FLayer lyr = e.getAffectedLayer();
715

    
716
                                try {
717
                                        getViewPort().setExtent(lyr.getFullExtent());
718
                                } catch (DriverException e1) {
719
                                }
720
                        }
721

    
722
                        // Registramos al FMap como listener del legend de las capas
723
                        FLayer lyr = e.getAffectedLayer();
724

    
725
                        lyr.addLayerListener(eventBuffer);
726

    
727
                        if (lyr instanceof Classifiable) {
728
                                Classifiable c = (Classifiable) lyr;
729
                                c.addLegendListener(eventBuffer);
730
                        }
731

    
732
                        if (lyr instanceof Selectable) {
733
                                Selectable s = (Selectable) lyr;
734
                                s.addSelectionListener(eventBuffer);
735
                        }
736
                }
737

    
738
                /**
739
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoved(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
740
                 */
741
                public void layerMoved(LayerPositionEvent e) {
742
                }
743

    
744
                /**
745
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoved(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
746
                 */
747
                public void layerRemoved(LayerCollectionEvent e) {
748
                        FLayer lyr = e.getAffectedLayer();
749

    
750
                        lyr.removeLayerListener(eventBuffer);
751

    
752
                        if (lyr instanceof Classifiable) {
753
                                Classifiable c = (Classifiable) lyr;
754
                                c.removeLegendListener(eventBuffer);
755
                        }
756

    
757
                        if (lyr instanceof Selectable) {
758
                                Selectable s = (Selectable) lyr;
759
                                s.addSelectionListener(eventBuffer);
760
                        }
761
                }
762

    
763
                /**
764
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdding(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
765
                 */
766
                public void layerAdding(LayerCollectionEvent e)
767
                                throws CancelationException {
768
                }
769

    
770
                /**
771
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoving(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
772
                 */
773
                public void layerMoving(LayerPositionEvent e)
774
                                throws CancelationException {
775
                }
776

    
777
                /**
778
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoving(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
779
                 */
780
                public void layerRemoving(LayerCollectionEvent e)
781
                                throws CancelationException {
782
                }
783

    
784
                /**
785
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#activationChanged(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
786
                 */
787
                public void activationChanged(LayerCollectionEvent e)
788
                                throws CancelationException {
789
                }
790

    
791
                /**
792
                 * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#visibilityChanged(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
793
                 */
794
                public void visibilityChanged(LayerCollectionEvent e)
795
                                throws CancelationException {
796
                }
797
        }
798

    
799
        public void addAsCollectionListener(FLayers layers2) {
800
                layers2.addLayerCollectionListener(layerEventListener);
801
        }
802

    
803
        public GraphicLayer getGraphicsLayer() {
804
                return tracLayer;
805
        }
806

    
807
        public boolean equals(Object arg0) {
808
                FMap map = (FMap) arg0;
809
                if (super.equals(arg0))
810
                        return true;
811
                if (getLayers() == map.getLayers())
812
                        return true;
813
                boolean isEqual = true;
814
                if (map.getLayers().getLayersCount() == getLayers().getLayersCount()) {
815
                        for (int i = 0; i < getLayers().getLayersCount(); i++) {
816

    
817
                                if (!getLayers().getLayer(i).getName().equals(
818
                                                map.getLayers().getLayer(i).getName())) {
819
                                        isEqual = false;
820
                                }
821

    
822
                        }
823
                } else {
824
                        isEqual = false;
825
                }
826
                return isEqual;
827
        }
828

    
829
        public void addLayerError(String stringProperty) {
830
                layersError.add(stringProperty);
831
        }
832

    
833
        public ArrayList getLayersError() {
834
                return layersError;
835
        }
836

    
837
        public void clearErrors() {
838
                layersError.clear();
839
        }
840
}