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 | 40558 | jjdelcerro | /**
|
---|---|---|---|
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 | 40435 | jjdelcerro | /*
|
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 | } |