Statistics
| Revision:

svn-gvsig-desktop / tags / Root_FMap_piloto_CAD_Layout_version / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapControl.java @ 1664

History | View | Annotate | Download (15.8 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.Color;
44
import java.awt.Dimension;
45
import java.awt.Graphics;
46
import java.awt.Graphics2D;
47
import java.awt.event.ActionEvent;
48
import java.awt.event.ActionListener;
49
import java.awt.event.ComponentEvent;
50
import java.awt.event.ComponentListener;
51
import java.awt.event.MouseEvent;
52
import java.awt.event.MouseListener;
53
import java.awt.event.MouseMotionListener;
54
import java.awt.event.MouseWheelEvent;
55
import java.awt.event.MouseWheelListener;
56
import java.awt.image.BufferedImage;
57
import java.util.HashMap;
58
import java.util.Stack;
59

    
60
import javax.swing.JComponent;
61
import javax.swing.Timer;
62

    
63
import org.apache.log4j.Logger;
64
import org.cresques.cts.IProjection;
65
import org.cresques.cts.ProjectionPool;
66

    
67
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
68
import com.iver.cit.gvsig.fmap.operations.Cancellable;
69
import com.iver.cit.gvsig.fmap.tools.BehaviorException;
70
import com.iver.cit.gvsig.fmap.tools.CompoundBehavior;
71
import com.iver.cit.gvsig.fmap.tools.Behavior.Behavior;
72
import com.iver.utiles.exceptionHandling.ExceptionHandlingSupport;
73
import com.iver.utiles.exceptionHandling.ExceptionListener;
74

    
75

    
76
/**
77
 * MapControl.
78
 *
79
 * @author Fernando Gonz?lez Cort?s
80
 */
81
public class MapControl extends JComponent implements ComponentListener {
82
        /** Cuando la vista est? actualizada. */
83
        public static final int ACTUALIZADO = 0;
84

    
85
        /** Cuando la vista est? desactualizada. */
86
        public static final int DESACTUALIZADO = 1;
87
        private static Logger logger = Logger.getLogger(MapControl.class.getName());
88
        private FMap mapContext = null;
89
        private HashMap namesMapTools = new HashMap();
90
        private Stack toolStack = new Stack();
91
        private int status = DESACTUALIZADO;
92
        private BufferedImage image = null;
93
        private CancelDraw canceldraw;
94
        private boolean isCancelled = true;
95
        private Timer timer;
96
        protected ViewPort vp;
97
        private Drawer drawer;
98
        private MapToolListener mapToolListener = new MapToolListener();
99
        private MapContextListener mapContextListener = new MapContextListener();
100
        private ExceptionHandlingSupport exceptionHandlingSupport = new ExceptionHandlingSupport();
101

    
102
        /**
103
         * Crea un nuevo NewMapControl.
104
         */
105
        public MapControl() {
106
                setDoubleBuffered(false);
107
                setOpaque(true);
108
                status = DESACTUALIZADO;
109

    
110
                //Clase usada para cancelar el dibujado
111
                canceldraw = new CancelDraw();
112

    
113
                //Modelo de datos y ventana del mismo
114
                // TODO: Cuando creamos un mapControl, deber?amos asignar
115
                // la projecci?n por defecto con la que vayamos a trabajar.
116
                // 23030 es el c?digo EPSG del UTM30 elipsoide ED50
117
                vp = new ViewPort(ProjectionPool.get("EPSG:23030"));
118
                setMapContext(new FMap(vp));
119
                
120
                //eventos
121
                this.addComponentListener(this);
122
                this.addMouseListener(mapToolListener);
123
                this.addMouseMotionListener(mapToolListener);
124
                this.addMouseWheelListener(mapToolListener);
125

    
126
                //Timer para mostrar el redibujado mientras se dibuja
127
                timer = new Timer(300,
128
                                new ActionListener() {
129
                                        public void actionPerformed(ActionEvent e) {
130
                                                MapControl.this.repaint();
131
                                        }
132
                                });
133
        }
134

    
135
        /**
136
         * Inserta el modelo.
137
         *
138
         * @param model FMap.
139
         */
140
        public void setMapContext(FMap model) {
141
                if (mapContext != null) {
142
                        mapContext.removeAtomicEventListener(mapContextListener);
143
                }
144

    
145
                mapContext = model;
146

    
147
                if (mapContext.getViewPort() == null) {
148
                        mapContext.setViewPort(vp);
149
                } else {
150
                        vp = mapContext.getViewPort();
151

    
152
                        // vp.setImageSize(new Dimension(getWidth(), getHeight()));
153
                        //System.err.println("Viewport en setMapContext:" + vp);
154
                }
155

    
156
                mapContext.addAtomicEventListener(mapContextListener);
157

    
158
                status = DESACTUALIZADO;
159
        }
160

    
161
        /**
162
         * Devuelve la proyecci?n.
163
         *
164
         * @return Proyecci?n.
165
         */
166
        public IProjection getProjection() {
167
                return getMapContext().getProjection();
168
        }
169

    
170
        /**
171
         * Inserta una proyecci?n.
172
         *
173
         * @param proj Proyecci?n.
174
         */
175
        public void setProjection(IProjection proj) {
176
                getMapContext().setProjection(proj);
177
        }
178

    
179
        /**
180
         * Devuelve el modelo.
181
         *
182
         * @return FMap.
183
         */
184
        public FMap getMapContext() {
185
                return mapContext;
186
        }
187

    
188
        /**
189
         * Registra una herramienta (tool).
190
         *
191
         * @param name Nombre de la herramienta.
192
         * @param tool Herramienta.
193
         */
194
        public void addMapTool(String name, Behavior tool) {
195
                namesMapTools.put(name, tool);
196
                tool.setMapControl(this);
197
        }
198

    
199
        public void addMapTool(String name, Behavior[] tools){
200
                CompoundBehavior tool = new CompoundBehavior(tools);
201
                addMapTool(name, tool);
202
        }
203
        
204
        /**
205
         * DOCUMENT ME!
206
         *
207
         * @param toolName DOCUMENT ME!
208
         */
209
        public void pushTool(String toolName) {
210
                Behavior mapTool = (Behavior) namesMapTools.get(toolName);
211
                toolStack.push(mapTool);
212
                this.setCursor(mapTool.getCursor());
213
        }
214

    
215
        public void popTool(){
216
                toolStack.pop();
217
                this.setCursor(((Behavior)toolStack.peek()).getCursor());
218
        }
219
        
220
        public void setTool(String toolName){
221
                popTool();
222
                pushTool(toolName);
223
        }
224
        
225
        public Behavior getCurrentMapTool() {
226
                return (Behavior)toolStack.peek();
227
        }
228
        /**
229
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
230
         */
231
        public void cancelDrawing() {
232
                if (drawer != null) {
233
                        if (!drawer.isAlive()) {
234
                                return;
235
                        }
236
                }
237

    
238
                canceldraw.setCancel(true);
239

    
240
                while (!isCancelled) {
241
                        if (!drawer.isAlive()) {
242
                            // Si hemos llegado aqu? con un thread vivo, seguramente
243
                            // no estamos actualizados.
244

    
245
                                break;
246
                        }
247
                    
248
                }
249
                canceldraw.setCancel(false);
250
                isCancelled = false;
251
        }
252

    
253
        /**
254
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
255
         */
256
        protected void paintComponent(Graphics g) {
257
                if (status == ACTUALIZADO) {
258
                        logger.debug("Dibujando la imagen obtenida");
259

    
260
                        /*
261
                         * Si hay un behaviour y la imagen es distinta de null se delega el dibujado
262
                         * en dicho behaviour
263
                         */
264
                        if (((Behavior)toolStack.peek() != null) && (image != null)) {
265
                                ((Behavior)toolStack.peek()).paintComponent(g);                           
266
                                System.out.println("Pinto ACTUALIZADO");
267
                        }
268
                } else if (status == DESACTUALIZADO) {
269
                        System.out.println("DESACTUALIZADO: Obteniendo la imagen de la cartograf?a");
270
                        /* if (isOpaque())
271
                        {
272
                            if (image==null)
273
                            {
274
                                g.setColor(vp.getBackColor());
275
                                g.fillRect(0,0,getWidth(), getHeight());                        
276
                            } 
277
                            // else g.drawImage(image,0,0,null);
278
                        } */
279

    
280
                        //Se crea la imagen con el color de fonde deseado
281
                        if (image == null)
282
                        {
283
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
284
                                                BufferedImage.TYPE_INT_ARGB);
285
                                vp.setImageSize(new Dimension(getWidth(), getHeight()));
286
                                Graphics gTemp = image.createGraphics();
287
                            Color theBackColor = vp.getBackColor();
288
                            if (theBackColor == null)
289
                                gTemp.setColor(Color.WHITE);
290
                            else
291
                                gTemp.setColor(theBackColor);
292
                                
293
                                gTemp.fillRect(0,0,getWidth(), getHeight());
294
                                gTemp.dispose();
295
                                // g.drawImage(image,0,0,null);
296
                                System.out.println("Imagen con null en DESACTUALIZADO");
297
                        }
298
                        g.drawImage(image,0,0,null);
299
                        
300
                        Graphics imgg = image.createGraphics();
301

    
302
                        //Se cancela el dibujado anterior
303
                        cancelDrawing();
304

    
305
                        drawer = new Drawer(image, (Graphics2D) imgg, canceldraw);
306
                        drawer.start();
307
                        //Se lanza el tread de dibujado
308
                        timer.start();
309
                        
310
                        status = ACTUALIZADO;
311

    
312
                        // repaint();
313
                }
314
        }
315

    
316
        /**
317
         * Devuelve la imagen de la vista.
318
         *
319
         * @return imagen.
320
         */
321
        public BufferedImage getImage() {
322
                return image;
323
        }
324

    
325
        /**
326
         * Marca el mapa para que en el pr?ximo redibujado se acceda a la
327
         * cartograf?a para reobtener la imagen
328
         * @param doClear TODO
329
         */
330
        public void drawMap(boolean doClear) {
331
                status = DESACTUALIZADO;
332
                if (doClear) image = null; // Se usa para el PAN
333
                repaint();
334
        }
335

    
336
        /**
337
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
338
         */
339
        public void componentHidden(ComponentEvent e) {
340
        }
341

    
342
        /**
343
         * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
344
         */
345
        public void componentMoved(ComponentEvent e) {
346
        }
347

    
348
        /**
349
         * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
350
         */
351
        public void componentResized(ComponentEvent e) {
352
                /* image = new BufferedImage(this.getWidth(), this.getHeight(),
353
                                BufferedImage.TYPE_INT_ARGB);                
354
                Graphics gTemp = image.createGraphics();
355
                gTemp.setColor(vp.getBackColor());
356
                gTemp.fillRect(0,0,getWidth(), getHeight()); */
357
            image = null;
358
            vp.setImageSize(new Dimension(getWidth(), getHeight()));
359
                getMapContext().getViewPort().setScale();
360
                drawMap(false);
361
        }
362

    
363
        /**
364
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
365
         */
366
        public void componentShown(ComponentEvent e) {
367
        }
368

    
369
        /**
370
         * A?ade un listener de tipo ExceptionListener.
371
         *
372
         * @param o ExceptionListener.
373
         */
374
        public void addExceptionListener(ExceptionListener o) {
375
                exceptionHandlingSupport.addExceptionListener(o);
376
        }
377

    
378
        /**
379
         * Borra la ExceptioListener que se pasa como par?metro.
380
         *
381
         * @param o ExceptionListener.
382
         *
383
         * @return True si se borra correctamente.
384
         */
385
        public boolean removeExceptionListener(ExceptionListener o) {
386
                return exceptionHandlingSupport.removeExceptionListener(o);
387
        }
388

    
389
        /**
390
         * Lanza una Excepci?n.
391
         *
392
         * @param t Excepci?n.
393
         */
394
        private void throwException(Throwable t) {
395
                exceptionHandlingSupport.throwException(t);
396
        }
397

    
398
        /**
399
         * Clase utilizada para dibujar las capas.
400
         *
401
         * @author Vicente Caballero Navarro
402
         */
403
        public class Drawer extends Thread {
404
                private Graphics g;
405
                private BufferedImage image;
406
                private CancelDraw cancel;
407
                private boolean threadCancel = false;
408

    
409
                /**
410
                 * Crea un nuevo Drawer.
411
                 *
412
                 * @param image
413
                 * @param g
414
                 * @param cancel
415
                 */
416
                public Drawer(BufferedImage image, Graphics g, CancelDraw cancel) {
417
                        this.g = g;
418
                        this.image = image;
419
                        this.cancel = cancel;
420
                }
421

    
422
                /**
423
                 * @see java.lang.Runnable#run()
424
                 */
425
                public void run() {
426
                        try {
427
                                synchronized (Drawer.class) {
428
                                    Graphics2D g = image.createGraphics();
429
                                    ViewPort viewPort = mapContext.getViewPort();
430
                                    Color theBackColor = viewPort.getBackColor();
431
                                    if (theBackColor == null)
432
                                        g.setColor(Color.WHITE);
433
                                    else
434
                                        g.setColor(theBackColor);
435
                                        g.fillRect(0, 0, viewPort.getImageWidth(), viewPort.getImageHeight());
436

    
437
                                        mapContext.draw(image, g, cancel);
438

    
439
                                        isCancelled = true;
440
                                        timer.stop();
441
                                        repaint();
442
                                    
443
                                }
444
                        } catch (Throwable e) {
445
                            timer.stop();
446
                                isCancelled = true;
447
                                throwException(e);
448
                        } finally {
449
                        }
450
                }
451
        }
452

    
453
        /**
454
         * Clase para cancelar el dibujado.
455
         *
456
         * @author Fernando Gonz?lez Cort?s
457
         */
458
        public class CancelDraw implements Cancellable {
459
                private boolean cancel = false;
460

    
461
                /**
462
                 * Crea un nuevo CancelDraw.
463
                 */
464
                public CancelDraw() {
465
                }
466

    
467
                /**
468
                 * Insertar si se debe cancelar el dibujado.
469
                 *
470
                 * @param b true si se debe cancelar el dibujado.
471
                 */
472
                public void setCancel(boolean b) {
473
                        cancel = b;
474
                }
475

    
476
                /**
477
                 * @see com.iver.cit.gvsig.fmap.operations.Cancellable#isCanceled()
478
                 */
479
                public boolean isCanceled() {
480
                        return cancel;
481
                }
482
        }
483

    
484
        /**
485
         * Listener del MapTool.
486
         *
487
         * @author Fernando Gonz?lez Cort?s
488
         */
489
        public class MapToolListener implements MouseListener, MouseWheelListener,
490
                MouseMotionListener {
491
                /**
492
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
493
                 */
494
                public void mouseClicked(MouseEvent e) {
495
                        try {
496
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
497
                                for (int i = 0; i < b.length; i++) {
498
                                        b[i].mouseClicked(e);
499
                                }
500
                        } catch (BehaviorException t) {
501
                                throwException(t);
502
                        }
503
                }
504

    
505
                /**
506
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
507
                 */
508
                public void mouseEntered(MouseEvent e) {
509
                        try {
510
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
511
                                for (int i = 0; i < b.length; i++) {
512
                                        b[i].mouseEntered(e);
513
                                }
514
                        } catch (BehaviorException t) {
515
                                throwException(t);
516
                        }
517
                }
518

    
519
                /**
520
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
521
                 */
522
                public void mouseExited(MouseEvent e) {
523
                        try {
524
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
525
                                for (int i = 0; i < b.length; i++) {
526
                                        b[i].mouseExited(e);
527
                                }
528
                        } catch (BehaviorException t) {
529
                                throwException(t);
530
                        }
531
                }
532

    
533
                /**
534
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
535
                 */
536
                public void mousePressed(MouseEvent e) {
537
                        try {
538
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
539
                                for (int i = 0; i < b.length; i++) {
540
                                        b[i].mousePressed(e);
541
                                }
542
                        } catch (BehaviorException t) {
543
                                throwException(t);
544
                        }
545
                }
546

    
547
                /**
548
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
549
                 */
550
                public void mouseReleased(MouseEvent e) {
551
                        try {
552
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
553
                                for (int i = 0; i < b.length; i++) {
554
                                        b[i].mouseReleased(e);
555
                                }
556
                        } catch (BehaviorException t) {
557
                                throwException(t);
558
                        }
559
                }
560

    
561
                /**
562
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
563
                 */
564
                public void mouseWheelMoved(MouseWheelEvent e) {
565
                        try {
566
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
567
                                for (int i = 0; i < b.length; i++) {
568
                                        b[i].mouseWheelMoved(e);
569
                                }
570
                        } catch (BehaviorException t) {
571
                                throwException(t);
572
                        }
573
                }
574

    
575
                /**
576
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
577
                 */
578
                public void mouseDragged(MouseEvent e) {
579
                        try {
580
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
581
                                for (int i = 0; i < b.length; i++) {
582
                                        b[i].mouseDragged(e);
583
                                }
584
                        } catch (BehaviorException t) {
585
                                throwException(t);
586
                        }
587
                }
588

    
589
                /**
590
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
591
                 */
592
                public void mouseMoved(MouseEvent e) {
593
                        try {
594
                                Behavior[] b = (Behavior[]) toolStack.toArray(new Behavior[]{});
595
                                for (int i = 0; i < b.length; i++) {
596
                                        b[i].mouseMoved(e);
597
                                }
598
                        } catch (BehaviorException t) {
599
                                throwException(t);
600
                        }
601
                }
602
        }
603

    
604
        /**
605
         * Listener sobre el MapContext.
606
         *
607
         * @author Fernando Gonz?lez Cort?s
608
         */
609
        public class MapContextListener implements AtomicEventListener {
610
                /**
611
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
612
                 */
613
                public void atomicEvent(AtomicEvent e) {
614
                        boolean redraw = false;
615
                        LayerEvent[] layerEvents = e.getLayerEvents();
616

    
617
                        for (int i = 0; i < layerEvents.length; i++) {
618
                                if (layerEvents[i].getProperty().equals("visible")) {
619
                                        redraw = true;
620
                                }
621
                        }
622

    
623
                        if (e.getColorEvents().length > 0) {
624
                                redraw = true;
625
                        }
626

    
627
                        if (e.getExtentEvents().length > 0) {
628
                                redraw = true;
629
                        }
630

    
631
                        if (e.getLayerCollectionEvents().length > 0) {
632
                                redraw = true;
633
                        }
634

    
635
                        if (e.getLegendEvents().length > 0) {
636
                                redraw = true;
637
                        }
638

    
639
                        if (e.getSelectionEvents().length > 0) {
640
                                redraw = true;
641
                        }
642

    
643
                        if (redraw) {
644
                                MapControl.this.drawMap(false);
645
                        }
646
                }
647
        }
648
        public ViewPort getViewPort() {
649
                return vp;
650
        }
651
}