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 @ 44035
History | View | Annotate | Download (10.9 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 | 40596 | jjdelcerro | |
25 | 40435 | jjdelcerro | package org.gvsig.app.project.documents.view; |
26 | |||
27 | import java.awt.BasicStroke; |
||
28 | import java.awt.Color; |
||
29 | import java.awt.Graphics; |
||
30 | import java.awt.Graphics2D; |
||
31 | 41098 | jldominguez | import java.awt.Point; |
32 | 40435 | jjdelcerro | import java.awt.geom.AffineTransform; |
33 | import java.awt.geom.Line2D; |
||
34 | import java.awt.geom.Point2D; |
||
35 | import java.awt.geom.Rectangle2D; |
||
36 | import java.awt.image.BufferedImage; |
||
37 | |||
38 | import org.cresques.cts.IProjection; |
||
39 | import org.gvsig.app.project.documents.view.toolListeners.MapOverviewChangeZoomListener; |
||
40 | import org.gvsig.app.project.documents.view.toolListeners.MapOverviewListener; |
||
41 | import org.gvsig.app.project.documents.view.toolListeners.MapOverviewPanListener; |
||
42 | import org.gvsig.fmap.dal.exception.ReadException; |
||
43 | import org.gvsig.fmap.geom.primitive.Envelope; |
||
44 | import org.gvsig.fmap.mapcontext.MapContext; |
||
45 | import org.gvsig.fmap.mapcontext.ViewPort; |
||
46 | import org.gvsig.fmap.mapcontext.events.ColorEvent; |
||
47 | import org.gvsig.fmap.mapcontext.events.ExtentEvent; |
||
48 | import org.gvsig.fmap.mapcontext.events.ProjectionEvent; |
||
49 | import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener; |
||
50 | import org.gvsig.fmap.mapcontrol.MapControl; |
||
51 | import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior; |
||
52 | import org.gvsig.fmap.mapcontrol.tools.Behavior.DraggerBehavior; |
||
53 | import org.gvsig.fmap.mapcontrol.tools.Behavior.PointBehavior; |
||
54 | import org.gvsig.fmap.mapcontrol.tools.Behavior.RectangleBehavior; |
||
55 | |||
56 | |||
57 | |||
58 | /**
|
||
59 | * <p>Lightweight <code>MapControl</code> that uses another <code>MapControl</code>'s <code>MapContext</code>, and updates
|
||
60 | * any rectangular extent selected, to the associated <code>MapControl</code>.</p>
|
||
61 | *
|
||
62 | * <p>Both <code>MapControl</code> instances work in the same projection. And, always, the not undefined <i>adjusted extent</i>
|
||
63 | * of the associated one, will be enhanced as a red-bordered grey-filled rectangle in this one. Furthermore, draws a horizontal and vertical
|
||
64 | * this component's width or height, black lines centered in that rectangle.</p>
|
||
65 | *
|
||
66 | * @author FJP
|
||
67 | */
|
||
68 | public class MapOverview extends MapControl implements ViewPortListener { |
||
69 | /**
|
||
70 | *
|
||
71 | */
|
||
72 | private static final long serialVersionUID = -2849739771493279542L; |
||
73 | |||
74 | /**
|
||
75 | * <p>Associated <code>MapControl</code> instance that this component represents its overview.</p>
|
||
76 | */
|
||
77 | private MapControl m_MapAssoc;
|
||
78 | |||
79 | /**
|
||
80 | * <p>Determines that's the first time this component is going to be painted.</p>
|
||
81 | */
|
||
82 | boolean first = true; |
||
83 | |||
84 | /**
|
||
85 | * <p>Tool listener used to apply a <i>zoom out</i> operation in this component graphical information.</p>
|
||
86 | */
|
||
87 | private MapOverviewListener movl;
|
||
88 | |||
89 | /**
|
||
90 | * <p>Tool listener used to allow user work with this component applying <i>pan</i> operations.</p>
|
||
91 | */
|
||
92 | private MapOverviewPanListener movpl;
|
||
93 | |||
94 | /**
|
||
95 | * <p>Tool listener used to allow user work with this component applying <i>pan</i> operations.</p>
|
||
96 | */
|
||
97 | private MapOverviewChangeZoomListener movczl;
|
||
98 | |||
99 | /**
|
||
100 | * <p>Rectangular area selected in this component, that will be the extent of the associated <code>MapControl</code> instance.</p>
|
||
101 | */
|
||
102 | private Envelope extent;
|
||
103 | |||
104 | /**
|
||
105 | * <p>Double buffer used to paint this component graphical information.</p>
|
||
106 | */
|
||
107 | private BufferedImage image; |
||
108 | |||
109 | /**
|
||
110 | * <p>Creates a <code>MapOverview</code> instance associated to <code>mapAssoc</code>.</p>
|
||
111 | *
|
||
112 | * @param mapAssoc <code>MapControl</code> this component will be the overview
|
||
113 | */
|
||
114 | public MapOverview(MapControl mapAssoc) {
|
||
115 | super();
|
||
116 | this.setName("MapOverview"); |
||
117 | // super.vp.setBackColor(new Color(230,230,230));
|
||
118 | m_MapAssoc = mapAssoc; |
||
119 | |||
120 | // setModel((FMap) m_MapAssoc.getMapContext().clone()); // Lo inicializamos con
|
||
121 | // los mismos temas que tenga el grande.
|
||
122 | movl = new MapOverviewListener(this); |
||
123 | movpl = new MapOverviewPanListener(this); |
||
124 | movczl = new MapOverviewChangeZoomListener(this); |
||
125 | addBehavior( |
||
126 | "zoomtopoint",
|
||
127 | new Behavior[]{ |
||
128 | new PointBehavior(movl),
|
||
129 | new RectangleBehavior(movczl),
|
||
130 | new DraggerBehavior(movczl),
|
||
131 | new DraggerBehavior(movpl)
|
||
132 | } |
||
133 | ); |
||
134 | |||
135 | // setCursor(movl.getCursor());
|
||
136 | 43480 | jjdelcerro | setDefaultMouseWheelEnabled(false);
|
137 | |||
138 | 40435 | jjdelcerro | setTool("zoomtopoint");
|
139 | getGrid().setShowGrid(false);
|
||
140 | getGrid().setAdjustGrid(false);
|
||
141 | } |
||
142 | |||
143 | /**
|
||
144 | * @see MapControl#getMapContext()
|
||
145 | */
|
||
146 | public MapContext getAssociatedMapContext() {
|
||
147 | return m_MapAssoc.getMapContext();
|
||
148 | } |
||
149 | |||
150 | /**
|
||
151 | * <p>Gets the <code>MapControl</code> instance that wrappers.</p>
|
||
152 | *
|
||
153 | * @return the <code>MapControl</code> instance that wrappers
|
||
154 | */
|
||
155 | public MapControl getAssociatedMapControl(){
|
||
156 | return m_MapAssoc;
|
||
157 | } |
||
158 | |||
159 | /*
|
||
160 | * (non-Javadoc)
|
||
161 | * @see com.iver.cit.gvsig.fmap.ViewPortListener#extentChanged(com.iver.cit.gvsig.fmap.ExtentEvent)
|
||
162 | */
|
||
163 | public void extentChanged(ExtentEvent evExtent) { |
||
164 | // Nos llega el nuevo extent del FMap asociado, as? que dibujamos nuestro
|
||
165 | // rect?ngulo para mostrar la zona de dibujo del otro mapa.
|
||
166 | repaint(); |
||
167 | } |
||
168 | |||
169 | /**
|
||
170 | * <p>If this had no extent, calls {@link #delModel() #delModel()}, otherwise recalculates this
|
||
171 | * component's view port extent as the union of all extents of all layers of this map.</p>
|
||
172 | */
|
||
173 | public void refreshExtent() { |
||
174 | try {
|
||
175 | if (this.getMapContext().getFullEnvelope()!=null){ |
||
176 | this.getMapContext().getViewPort().setEnvelope(this.getMapContext().getFullEnvelope()); |
||
177 | 41039 | jldominguez | } else {
|
178 | // delModel();
|
||
179 | 40435 | jjdelcerro | } |
180 | } catch (ReadException e1) {
|
||
181 | e1.printStackTrace(); |
||
182 | } |
||
183 | } |
||
184 | |||
185 | /**
|
||
186 | * <p>Repaints this component updating its <i>extent</i>.</p>
|
||
187 | *
|
||
188 | * @param r the new extent
|
||
189 | */
|
||
190 | public void refreshOverView(Envelope r){ |
||
191 | extent=r; |
||
192 | repaint(); |
||
193 | } |
||
194 | |||
195 | /**
|
||
196 | * <p>Paints this component's graphical information using a 8-bit RGBA color double buffer, drawing a red-bordered
|
||
197 | * grey-filled rectangle enhancing the extent selected, and a horizontal and vertical this component's width or
|
||
198 | * height, black lines centered in that rectangle.</p>
|
||
199 | */
|
||
200 | protected void paintComponent(Graphics g) { |
||
201 | getGrid().setShowGrid(false);
|
||
202 | getGrid().setAdjustGrid(false);
|
||
203 | super.paintComponent(g);
|
||
204 | |||
205 | 41041 | jldominguez | if (m_MapAssoc.getMapContext().getViewPort().getEnvelope() != null && |
206 | getMapContext().getViewPort().getEnvelope() != null &&
|
||
207 | getMapContext().getLayers().getLayersCount() > 0) {
|
||
208 | |||
209 | 40435 | jjdelcerro | if (first) {
|
210 | first = false;
|
||
211 | repaint(); |
||
212 | return;
|
||
213 | } |
||
214 | image = new BufferedImage(this.getWidth(), this.getHeight(), |
||
215 | BufferedImage.TYPE_INT_ARGB);
|
||
216 | ViewPort vp = getMapContext().getViewPort(); |
||
217 | Envelope extentView=vp.getAdjustedEnvelope(); |
||
218 | ViewPort vpOrig = m_MapAssoc.getMapContext().getViewPort(); |
||
219 | if (extent==null) { |
||
220 | extent=vpOrig.getAdjustedEnvelope(); |
||
221 | } |
||
222 | // Dibujamos el extent del mapa asociado.
|
||
223 | Graphics2D g2 = (Graphics2D) image.getGraphics(); |
||
224 | g2.setTransform(vp.getAffineTransform()); |
||
225 | |||
226 | g2.setStroke(new BasicStroke((float) vp.getDist1pixel())); |
||
227 | |||
228 | g2.setColor(Color.red);
|
||
229 | Rectangle2D extentToDraw=new Rectangle2D.Double(extent.getMinimum(0),extent.getMinimum(1),extent.getLength(0),extent.getLength(1)); |
||
230 | g2.draw(extentToDraw); |
||
231 | g2.setColor(new Color(100,100,100,100)); |
||
232 | g2.fill(extentToDraw); |
||
233 | // dibujamos las l?neas vertical y horizontal
|
||
234 | Point2D pRightUp = vp.toMapPoint(getWidth(), 0); |
||
235 | |||
236 | Line2D.Double linVert = new Line2D.Double(extentToDraw.getCenterX(), |
||
237 | extentView.getMinimum(1), extentToDraw.getCenterX(),
|
||
238 | pRightUp.getY()); |
||
239 | Line2D.Double linHoriz = new Line2D.Double(extentView.getMinimum(0), |
||
240 | extentToDraw.getCenterY(), pRightUp.getX(), |
||
241 | extentToDraw.getCenterY()); |
||
242 | |||
243 | g2.setColor(Color.darkGray);
|
||
244 | g2.draw(linVert); |
||
245 | g2.draw(linHoriz); |
||
246 | g.drawImage(image,0,0,this); |
||
247 | g2.setTransform(new AffineTransform()); |
||
248 | extent=null;
|
||
249 | } |
||
250 | |||
251 | } |
||
252 | |||
253 | /**
|
||
254 | * <p>Sets a <code>MapContext</code> to this component, configuring it to manage view port events produced
|
||
255 | * in the associated <code>MapControl</code> and this one's view port.</p>
|
||
256 | *
|
||
257 | * <p>This <code>MapContext</code>'s projection will be the same as the associated <code>MapControl</code>'s one.</p>
|
||
258 | *
|
||
259 | * <p>Setting the model includes the following steps:
|
||
260 | * <ul>
|
||
261 | * <li><b>1.-</b> set <code>model</code> as the <code>MapContext</code> of <code>this</code>.</li>
|
||
262 | * <li><b>2.-</b> set as <code>model</code> projection, the associated <code>MapControl<code>'s projection.</li>
|
||
263 | * <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>
|
||
264 | * <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>
|
||
265 | * </ul>
|
||
266 | * </p>
|
||
267 | *
|
||
268 | * @param model data to set
|
||
269 | */
|
||
270 | public void setModel(MapContext model) { |
||
271 | this.setMapContext(model);
|
||
272 | model.setProjection(m_MapAssoc.getMapContext().getProjection()); |
||
273 | m_MapAssoc.getMapContext().getViewPort().addViewPortListener(this);
|
||
274 | getMapContext().getViewPort().addViewPortListener(this);
|
||
275 | } |
||
276 | |||
277 | /**
|
||
278 | * <p>Removes this component as listener of the the associated <code>MapControl</code> and this one's view port. Besides,
|
||
279 | * removes the extent.</p>
|
||
280 | */
|
||
281 | 41039 | jldominguez | /*
|
282 | 40435 | jjdelcerro | private void delModel(){
|
283 | this.getMapContext().getViewPort().setEnvelope(null);
|
||
284 | m_MapAssoc.getMapContext().getViewPort().removeViewPortListener(this);
|
||
285 | getMapContext().getViewPort().removeViewPortListener(this);
|
||
286 | }
|
||
287 | 41039 | jldominguez | */
|
288 | 40435 | jjdelcerro | |
289 | /*
|
||
290 | * (non-Javadoc)
|
||
291 | * @see com.iver.cit.gvsig.fmap.ViewPortListener#backColorChanged(com.iver.cit.gvsig.fmap.ColorEvent)
|
||
292 | */
|
||
293 | public void backColorChanged(ColorEvent e) { |
||
294 | // do nothing
|
||
295 | } |
||
296 | |||
297 | /**
|
||
298 | * @see ViewPortListener#projectionChanged(ProjectionEvent)
|
||
299 | *
|
||
300 | * @see MapControl#setProjection(IProjection)
|
||
301 | */
|
||
302 | public void projectionChanged(ProjectionEvent e) { |
||
303 | super.setProjection(e.getNewProjection());
|
||
304 | |||
305 | } |
||
306 | |||
307 | /**
|
||
308 | * <p>Unimplemented.</p>
|
||
309 | *
|
||
310 | * <p>Can't change the projection, because must be the same as the one of the
|
||
311 | * associated <code>MapControl</code> instance.</p>
|
||
312 | */
|
||
313 | public void setProjection(IProjection proj) { |
||
314 | //No permitimos cambiar la proyeccion
|
||
315 | //ya que debe ser la misma que la del
|
||
316 | //MapControl asociado
|
||
317 | return;
|
||
318 | } |
||
319 | 41098 | jldominguez | |
320 | public void calculateSnapPoint(Point point) { |
||
321 | /*
|
||
322 | * This is the behavior of a MapControl when there is no snapping.
|
||
323 | * We do the same and save a lot of computations
|
||
324 | */
|
||
325 | adjustedPoint = point; |
||
326 | mapAdjustedPoint = null;
|
||
327 | } |
||
328 | |||
329 | |||
330 | |||
331 | 40435 | jjdelcerro | } |