Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / MapOverview.java @ 40558

History | View | Annotate | Download (11.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25
 * Created on 21-jun-2004
26
 *
27
 * TODO To change the template for this generated file go to
28
 * Window - Preferences - Java - Code Generation - Code and Comments
29
 */
30
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
31
 *
32
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
33
 *
34
 * This program is free software; you can redistribute it and/or
35
 * modify it under the terms of the GNU General Public License
36
 * as published by the Free Software Foundation; either version 2
37
 * of the License, or (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
47
 *
48
 * For more information, contact:
49
 *
50
 *  Generalitat Valenciana
51
 *   Conselleria d'Infraestructures i Transport
52
 *   Av. Blasco Ib??ez, 50
53
 *   46010 VALENCIA
54
 *   SPAIN
55
 *
56
 *      +34 963862235
57
 *   gvsig@gva.es
58
 *      www.gvsig.gva.es
59
 *
60
 *    or
61
 *
62
 *   IVER T.I. S.A
63
 *   Salamanca 50
64
 *   46005 Valencia
65
 *   Spain
66
 *
67
 *   +34 963163400
68
 *   dac@iver.es
69
 */
70
package org.gvsig.app.project.documents.view;
71

    
72
import java.awt.BasicStroke;
73
import java.awt.Color;
74
import java.awt.Graphics;
75
import java.awt.Graphics2D;
76
import java.awt.geom.AffineTransform;
77
import java.awt.geom.Line2D;
78
import java.awt.geom.Point2D;
79
import java.awt.geom.Rectangle2D;
80
import java.awt.image.BufferedImage;
81

    
82
import org.cresques.cts.IProjection;
83
import org.gvsig.app.project.documents.view.toolListeners.MapOverviewChangeZoomListener;
84
import org.gvsig.app.project.documents.view.toolListeners.MapOverviewListener;
85
import org.gvsig.app.project.documents.view.toolListeners.MapOverviewPanListener;
86
import org.gvsig.fmap.dal.exception.ReadException;
87
import org.gvsig.fmap.geom.primitive.Envelope;
88
import org.gvsig.fmap.mapcontext.MapContext;
89
import org.gvsig.fmap.mapcontext.ViewPort;
90
import org.gvsig.fmap.mapcontext.events.ColorEvent;
91
import org.gvsig.fmap.mapcontext.events.ExtentEvent;
92
import org.gvsig.fmap.mapcontext.events.ProjectionEvent;
93
import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener;
94
import org.gvsig.fmap.mapcontrol.MapControl;
95
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
96
import org.gvsig.fmap.mapcontrol.tools.Behavior.DraggerBehavior;
97
import org.gvsig.fmap.mapcontrol.tools.Behavior.PointBehavior;
98
import org.gvsig.fmap.mapcontrol.tools.Behavior.RectangleBehavior;
99

    
100

    
101

    
102
/**
103
 * <p>Lightweight <code>MapControl</code> that uses another <code>MapControl</code>'s <code>MapContext</code>, and updates
104
 *  any rectangular extent selected, to the associated <code>MapControl</code>.</p>
105
 *
106
 * <p>Both <code>MapControl</code> instances work in the same projection. And, always, the not undefined <i>adjusted extent</i>
107
 *  of the associated one, will be enhanced as a red-bordered grey-filled rectangle in this one. Furthermore, draws a horizontal and vertical
108
 *  this component's width or height, black lines centered in that rectangle.</p>
109
 *
110
 * @author FJP
111
 */
112
public class MapOverview extends MapControl implements ViewPortListener {
113
        /**
114
         * 
115
         */
116
        private static final long serialVersionUID = -2849739771493279542L;
117

    
118
        /**
119
         * <p>Associated <code>MapControl</code> instance that this component represents its overview.</p>
120
         */
121
        private MapControl m_MapAssoc;
122

    
123
        /**
124
         * <p>Determines that's the first time this component is going to be painted.</p>
125
         */
126
        boolean first = true;
127

    
128
        /**
129
         * <p>Tool listener used to apply a <i>zoom out</i> operation in this component graphical information.</p>
130
         */
131
        private MapOverviewListener movl;
132

    
133
        /**
134
         * <p>Tool listener used to allow user work with this component applying <i>pan</i> operations.</p>
135
         */
136
        private MapOverviewPanListener movpl;
137

    
138
        /**
139
         * <p>Tool listener used to allow user work with this component applying <i>pan</i> operations.</p>
140
         */
141
        private MapOverviewChangeZoomListener movczl;
142

    
143
        /**
144
         * <p>Rectangular area selected in this component, that will be the extent of the associated <code>MapControl</code> instance.</p>
145
         */
146
        private Envelope extent;
147

    
148
        /**
149
         * <p>Double buffer used to paint this component graphical information.</p>
150
         */
151
        private BufferedImage image;
152

    
153
        /**
154
         * <p>Creates a <code>MapOverview</code> instance associated to <code>mapAssoc</code>.</p>
155
         *
156
         * @param mapAssoc <code>MapControl</code> this component will be the overview
157
         */
158
        public MapOverview(MapControl mapAssoc) {
159
                super();
160
                this.setName("MapOverview");
161
                // super.vp.setBackColor(new Color(230,230,230));
162
                m_MapAssoc = mapAssoc;
163

    
164
                // setModel((FMap) m_MapAssoc.getMapContext().clone()); // Lo inicializamos con
165
                // los mismos temas que tenga el grande.
166
                movl = new MapOverviewListener(this);
167
                movpl = new MapOverviewPanListener(this);
168
                movczl = new MapOverviewChangeZoomListener(this);
169
                addBehavior(
170
                                "zoomtopoint",
171
                                new Behavior[]{
172
                                                new PointBehavior(movl),
173
                                                new RectangleBehavior(movczl),
174
                                                new DraggerBehavior(movczl),
175
                                                new DraggerBehavior(movpl)
176
                                }
177
                );
178

    
179
//                setCursor(movl.getCursor());
180

    
181
                setTool("zoomtopoint");
182
                getGrid().setShowGrid(false);
183
                getGrid().setAdjustGrid(false);
184
        }
185

    
186
        /**
187
         * @see MapControl#getMapContext()
188
         */
189
        public MapContext getAssociatedMapContext() {
190
                return m_MapAssoc.getMapContext();
191
        }
192

    
193
        /**
194
         * <p>Gets the <code>MapControl</code> instance that wrappers.</p>
195
         *
196
         * @return the <code>MapControl</code> instance that wrappers
197
         */
198
        public MapControl getAssociatedMapControl(){
199
                return m_MapAssoc;
200
        }
201

    
202
        /*
203
         * (non-Javadoc)
204
         * @see com.iver.cit.gvsig.fmap.ViewPortListener#extentChanged(com.iver.cit.gvsig.fmap.ExtentEvent)
205
         */
206
        public void extentChanged(ExtentEvent evExtent) {
207
                // Nos llega el nuevo extent del FMap asociado, as? que dibujamos nuestro
208
                // rect?ngulo para mostrar la zona de dibujo del otro mapa.
209
                repaint();
210
        }
211

    
212
        /**
213
         * <p>If this had no extent, calls {@link #delModel() #delModel()}, otherwise recalculates this
214
         *  component's view port extent as the union of all extents of all layers of this map.</p>
215
         */
216
        public void refreshExtent() {
217
                try {
218
                if (this.getMapContext().getFullEnvelope()!=null){
219
                                this.getMapContext().getViewPort().setEnvelope(this.getMapContext().getFullEnvelope());
220
                }else{
221
                        delModel();
222
                }
223
                } catch (ReadException e1) {
224
                        e1.printStackTrace();
225
                }
226
        }
227

    
228
        /**
229
         * <p>Repaints this component updating its <i>extent</i>.</p>
230
         *
231
         * @param r the new extent
232
         */
233
        public void refreshOverView(Envelope r){
234
                extent=r;
235
                repaint();
236
        }
237

    
238
        /**
239
         * <p>Paints this component's graphical information using a 8-bit RGBA color double buffer, drawing a red-bordered
240
         *  grey-filled rectangle enhancing the extent selected, and a horizontal and vertical this component's width or
241
         *  height, black lines centered in that rectangle.</p>
242
         */
243
        protected void paintComponent(Graphics g) {
244
                getGrid().setShowGrid(false);
245
                getGrid().setAdjustGrid(false);
246
                super.paintComponent(g);
247
                
248
                if ((m_MapAssoc.getMapContext().getViewPort().getEnvelope() != null) &&
249
                                        (getMapContext().getViewPort().getEnvelope() != null)) {
250
                                if (first) {
251
                                        first = false;
252
                                        repaint();
253
                                        return;
254
                                }
255
                                image = new BufferedImage(this.getWidth(), this.getHeight(),
256
                                    BufferedImage.TYPE_INT_ARGB);
257
                                ViewPort vp = getMapContext().getViewPort();
258
                                Envelope extentView=vp.getAdjustedEnvelope();
259
                                ViewPort vpOrig = m_MapAssoc.getMapContext().getViewPort();
260
                                if (extent==null) {
261
                                        extent=vpOrig.getAdjustedEnvelope();
262
                                }
263
                                // Dibujamos el extent del mapa asociado.
264
                                Graphics2D g2 = (Graphics2D) image.getGraphics();
265
                                g2.setTransform(vp.getAffineTransform());
266

    
267
                                g2.setStroke(new BasicStroke((float) vp.getDist1pixel()));
268

    
269
                                g2.setColor(Color.red);
270
                                Rectangle2D extentToDraw=new Rectangle2D.Double(extent.getMinimum(0),extent.getMinimum(1),extent.getLength(0),extent.getLength(1));
271
                                g2.draw(extentToDraw);
272
                                g2.setColor(new Color(100,100,100,100));
273
                                g2.fill(extentToDraw);
274
                                // dibujamos las l?neas vertical y horizontal
275
                                Point2D pRightUp = vp.toMapPoint(getWidth(), 0);
276

    
277
                                Line2D.Double linVert = new Line2D.Double(extentToDraw.getCenterX(),
278
                                                extentView.getMinimum(1), extentToDraw.getCenterX(),
279
                                                pRightUp.getY());
280
                                Line2D.Double linHoriz = new Line2D.Double(extentView.getMinimum(0),
281
                                                extentToDraw.getCenterY(), pRightUp.getX(),
282
                                                extentToDraw.getCenterY());
283

    
284
                                g2.setColor(Color.darkGray);
285
                                g2.draw(linVert);
286
                                g2.draw(linHoriz);
287
                                g.drawImage(image,0,0,this);
288
                                g2.setTransform(new AffineTransform());
289
                                extent=null;
290
                        }
291

    
292
        }
293

    
294
        /**
295
         * <p>Sets a <code>MapContext</code> to this component, configuring it to manage view port events produced
296
         *  in the associated <code>MapControl</code> and this one's view port.</p>
297
         *
298
         * <p>This <code>MapContext</code>'s projection will be the same as the associated <code>MapControl</code>'s one.</p>
299
         *
300
         * <p>Setting the model includes the following steps:
301
         *  <ul>
302
         *   <li><b>1.-</b> set <code>model</code> as the <code>MapContext</code> of <code>this</code>.</li>
303
         *   <li><b>2.-</b> set as <code>model</code> projection, the associated <code>MapControl<code>'s projection.</li>
304
         *   <li><b>3.-</b> set <code>this</code> as <i>view port</i> listener of the associated <code>MapControl</code>'s <i>view port</i>.</li>
305
         *   <li><b>4.-</b> set <code>this</code> as <i>view port</i> listener of this <code>MapContext</code>'s <i>view port</i></li>
306
         *  </ul>
307
         * </p>
308
         *
309
         * @param model data to set
310
         */
311
        public void setModel(MapContext model) {
312
                this.setMapContext(model);
313
                model.setProjection(m_MapAssoc.getMapContext().getProjection());
314
                m_MapAssoc.getMapContext().getViewPort().addViewPortListener(this);
315
                getMapContext().getViewPort().addViewPortListener(this);
316
        }
317

    
318
        /**
319
         * <p>Removes this component as listener of the the associated <code>MapControl</code> and this one's view port. Besides,
320
     *  removes the extent.</p>
321
         */
322
        private void delModel(){
323
                this.getMapContext().getViewPort().setEnvelope(null);
324
                m_MapAssoc.getMapContext().getViewPort().removeViewPortListener(this);
325
                getMapContext().getViewPort().removeViewPortListener(this);
326
        }
327

    
328
        /*
329
         * (non-Javadoc)
330
         * @see com.iver.cit.gvsig.fmap.ViewPortListener#backColorChanged(com.iver.cit.gvsig.fmap.ColorEvent)
331
         */
332
        public void backColorChanged(ColorEvent e) {
333
                // do nothing
334
        }
335

    
336
        /**
337
         * @see ViewPortListener#projectionChanged(ProjectionEvent)
338
         *
339
         * @see MapControl#setProjection(IProjection)
340
         */
341
        public void projectionChanged(ProjectionEvent e) {
342
                super.setProjection(e.getNewProjection());
343

    
344
        }
345

    
346
        /**
347
         * <p>Unimplemented.</p>
348
         *
349
         * <p>Can't change the projection, because must be the same as the one of the
350
         *  associated <code>MapControl</code> instance.</p>
351
         */
352
        public void setProjection(IProjection proj) {
353
                //No permitimos cambiar la proyeccion
354
                //ya que debe ser la misma que la del
355
                //MapControl asociado
356
                return;
357
        }
358
}