Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / MapControl.java @ 1303

History | View | Annotate | Download (14.7 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

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

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

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

    
74

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

    
84
        /** Cuando la vista est? desactualizada. */
85
        public static final int DESACTUALIZADO = 1;
86
        private static Logger logger = Logger.getLogger(MapControl.class.getName());
87
        private FMap mapContext = null;
88
        private HashMap namesMapTools = new HashMap();
89
        private Behavior currentMapTool = null;
90
        private int status = DESACTUALIZADO;
91
        private BufferedImage image = null;
92
        private String currentTool;
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 setTool(String toolName) {
210
                Behavior mapTool = (Behavior) namesMapTools.get(toolName);
211
                currentMapTool = mapTool;
212
                currentTool = toolName;
213
                this.setCursor(mapTool.getCursor());
214
        }
215

    
216
        /**
217
         * Devuelve el nombre de la herramienta seleccionada.
218
         *
219
         * @return nombre.
220
         */
221
        public String getTool() {
222
                return currentTool;
223
        }
224

    
225
        /**
226
         * Cancela el dibujado. Se espera a que la cancelaci?n surta efecto
227
         */
228
        public void cancelDrawing() {
229
                if (drawer != null) {
230
                        if (!drawer.isAlive()) {
231
                                return;
232
                        }
233
                }
234

    
235
                canceldraw.setCancel(true);
236

    
237
                while (!isCancelled) {
238
                        if (!drawer.isAlive()) {
239
                                        break;
240
                        }
241
                    
242
                }
243

    
244
                canceldraw.setCancel(false);
245
                isCancelled = false;
246
        }
247

    
248
        /**
249
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
250
         */
251
        protected void paintComponent(Graphics g) {
252
                if (status == ACTUALIZADO) {
253
                        logger.debug("Dibujando la imagen obtenida");
254

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

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

    
297
                        //Se lanza el tread de dibujado
298
                        timer.start();
299
                        //Se cancela el dibujado anterior
300
                        cancelDrawing();
301

    
302
                        drawer = new Drawer(image, (Graphics2D) imgg, canceldraw);
303
                        drawer.start();
304
                        
305
                        status = ACTUALIZADO;
306

    
307
                        // repaint();
308
                }
309
        }
310

    
311
        /**
312
         * Devuelve la imagen de la vista.
313
         *
314
         * @return imagen.
315
         */
316
        public BufferedImage getImage() {
317
                return image;
318
        }
319

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

    
331
        /**
332
         * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
333
         */
334
        public void componentHidden(ComponentEvent e) {
335
        }
336

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

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

    
358
        /**
359
         * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
360
         */
361
        public void componentShown(ComponentEvent e) {
362
        }
363

    
364
        /**
365
         * A?ade un listener de tipo ExceptionListener.
366
         *
367
         * @param o ExceptionListener.
368
         */
369
        public void addExceptionListener(ExceptionListener o) {
370
                exceptionHandlingSupport.addExceptionListener(o);
371
        }
372

    
373
        /**
374
         * Borra la ExceptioListener que se pasa como par?metro.
375
         *
376
         * @param o ExceptionListener.
377
         *
378
         * @return True si se borra correctamente.
379
         */
380
        public boolean removeExceptionListener(ExceptionListener o) {
381
                return exceptionHandlingSupport.removeExceptionListener(o);
382
        }
383

    
384
        /**
385
         * Lanza una Excepci?n.
386
         *
387
         * @param t Excepci?n.
388
         */
389
        private void throwException(Throwable t) {
390
                exceptionHandlingSupport.throwException(t);
391
        }
392

    
393
        /**
394
         * Clase utilizada para dibujar las capas.
395
         *
396
         * @author Vicente Caballero Navarro
397
         */
398
        public class Drawer extends Thread {
399
                private Graphics g;
400
                private BufferedImage image;
401
                private CancelDraw cancel;
402
                private boolean threadCancel = false;
403

    
404
                /**
405
                 * Crea un nuevo Drawer.
406
                 *
407
                 * @param image
408
                 * @param g
409
                 * @param cancel
410
                 */
411
                public Drawer(BufferedImage image, Graphics g, CancelDraw cancel) {
412
                        this.g = g;
413
                        this.image = image;
414
                        this.cancel = cancel;
415
                }
416

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

    
432
                                        mapContext.draw(image, g, cancel);
433

    
434
                                    timer.stop();
435
                                        isCancelled = true;
436
                                        repaint();
437
                                }
438
                        } catch (Throwable e) {
439
                            timer.stop();
440
                                isCancelled = true;
441
                                throwException(e);
442
                        } finally {
443
                        }
444
                }
445
        }
446

    
447
        /**
448
         * Clase para cancelar el dibujado.
449
         *
450
         * @author Fernando Gonz?lez Cort?s
451
         */
452
        public class CancelDraw implements Cancellable {
453
                private boolean cancel = false;
454

    
455
                /**
456
                 * Crea un nuevo CancelDraw.
457
                 */
458
                public CancelDraw() {
459
                }
460

    
461
                /**
462
                 * Insertar si se debe cancelar el dibujado.
463
                 *
464
                 * @param b true si se debe cancelar el dibujado.
465
                 */
466
                public void setCancel(boolean b) {
467
                        cancel = b;
468
                }
469

    
470
                /**
471
                 * @see com.iver.cit.gvsig.fmap.operations.Cancellable#isCanceled()
472
                 */
473
                public boolean isCanceled() {
474
                        return cancel;
475
                }
476
        }
477

    
478
        /**
479
         * Listener del MapTool.
480
         *
481
         * @author Fernando Gonz?lez Cort?s
482
         */
483
        public class MapToolListener implements MouseListener, MouseWheelListener,
484
                MouseMotionListener {
485
                /**
486
                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
487
                 */
488
                public void mouseClicked(MouseEvent e) {
489
                        try {
490
                                currentMapTool.mouseClicked(e);
491
                        } catch (BehaviorException t) {
492
                                throwException(t);
493
                        }
494
                }
495

    
496
                /**
497
                 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
498
                 */
499
                public void mouseEntered(MouseEvent e) {
500
                        try {
501
                                currentMapTool.mouseEntered(e);
502
                        } catch (BehaviorException t) {
503
                                throwException(t);
504
                        }
505
                }
506

    
507
                /**
508
                 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
509
                 */
510
                public void mouseExited(MouseEvent e) {
511
                        try {
512
                                currentMapTool.mouseExited(e);
513
                        } catch (BehaviorException t) {
514
                                throwException(t);
515
                        }
516
                }
517

    
518
                /**
519
                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
520
                 */
521
                public void mousePressed(MouseEvent e) {
522
                        try {
523
                                currentMapTool.mousePressed(e);
524
                        } catch (BehaviorException t) {
525
                                throwException(t);
526
                        }
527
                }
528

    
529
                /**
530
                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
531
                 */
532
                public void mouseReleased(MouseEvent e) {
533
                        try {
534
                                currentMapTool.mouseReleased(e);
535
                        } catch (BehaviorException t) {
536
                                throwException(t);
537
                        }
538
                }
539

    
540
                /**
541
                 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
542
                 */
543
                public void mouseWheelMoved(MouseWheelEvent e) {
544
                        try {
545
                                currentMapTool.mouseWheelMoved(e);
546
                        } catch (BehaviorException t) {
547
                                throwException(t);
548
                        }
549
                }
550

    
551
                /**
552
                 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
553
                 */
554
                public void mouseDragged(MouseEvent e) {
555
                        try {
556
                                currentMapTool.mouseDragged(e);
557
                        } catch (BehaviorException t) {
558
                                throwException(t);
559
                        }
560
                }
561

    
562
                /**
563
                 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
564
                 */
565
                public void mouseMoved(MouseEvent e) {
566
                        try {
567
                                currentMapTool.mouseMoved(e);
568
                        } catch (BehaviorException t) {
569
                                throwException(t);
570
                        }
571
                }
572
        }
573

    
574
        /**
575
         * Listener sobre el MapContext.
576
         *
577
         * @author Fernando Gonz?lez Cort?s
578
         */
579
        public class MapContextListener implements AtomicEventListener {
580
                /**
581
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
582
                 */
583
                public void atomicEvent(AtomicEvent e) {
584
                        boolean redraw = false;
585
                        LayerEvent[] layerEvents = e.getLayerEvents();
586

    
587
                        for (int i = 0; i < layerEvents.length; i++) {
588
                                if (layerEvents[i].getProperty().equals("visible")) {
589
                                        redraw = true;
590
                                }
591
                        }
592

    
593
                        if (e.getColorEvents().length > 0) {
594
                                redraw = true;
595
                        }
596

    
597
                        if (e.getExtentEvents().length > 0) {
598
                                redraw = true;
599
                        }
600

    
601
                        if (e.getLayerCollectionEvents().length > 0) {
602
                                redraw = true;
603
                        }
604

    
605
                        if (e.getLegendEvents().length > 0) {
606
                                redraw = true;
607
                        }
608

    
609
                        if (e.getSelectionEvents().length > 0) {
610
                                redraw = true;
611
                        }
612

    
613
                        if (redraw) {
614
                                MapControl.this.drawMap(false);
615
                        }
616
                }
617
        }
618
        public ViewPort getViewPort() {
619
                return vp;
620
        }
621
}