source: josm/trunk/src/org/openstreetmap/josm/gui/MapViewState.java@ 10343

Last change on this file since 10343 was 10343, checked in by Don-vip, 8 years ago

fix #12934 - Add new MapViewState class that stores the current state of the map view (patch by michael2402) - gsoc-core

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import java.awt.Point;
5import java.awt.geom.Point2D;
6import java.awt.geom.Point2D.Double;
7
8import javax.swing.SwingUtilities;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.Bounds;
12import org.openstreetmap.josm.data.ProjectionBounds;
13import org.openstreetmap.josm.data.coor.EastNorth;
14import org.openstreetmap.josm.data.coor.LatLon;
15import org.openstreetmap.josm.data.projection.Projection;
16
17/**
18 * This class represents a state of the {@link MapView}.
19 * @author Michael Zangl
20 * @since 10343
21 */
22public class MapViewState {
23
24 private final Projection projection = Main.getProjection();
25
26 private final int viewWidth;
27 private final int viewHeight;
28
29 private final double scale;
30
31 /**
32 * Top left {@link EastNorth} coordinate of the view.
33 */
34 private final EastNorth topLeft;
35
36 private final NavigatableComponent navigatableComponent;
37
38 /**
39 * Create a new {@link MapViewState} object for the given map view.
40 * @param navigatableComponent The view.
41 */
42 public MapViewState(NavigatableComponent navigatableComponent) {
43 this.navigatableComponent = navigatableComponent;
44 viewWidth = navigatableComponent.getWidth();
45 viewHeight = navigatableComponent.getHeight();
46
47 scale = navigatableComponent.getScale();
48 EastNorth center = navigatableComponent.getCenter();
49 topLeft = new EastNorth(center.east() - viewWidth / 2.0 * scale, center.north() + viewHeight / 2.0 * scale);
50 }
51
52 /**
53 * Gets the MapViewPoint representation for a position in view coordinates.
54 * @param x The x coordinate inside the view.
55 * @param y The y coordinate inside the view.
56 * @return The MapViewPoint.
57 */
58 public MapViewPoint getForView(double x, double y) {
59 return new MapViewViewPoint(x, y);
60 }
61
62 /**
63 * Gets the {@link MapViewPoint} for the given {@link EastNorth} coordinate.
64 * @param eastNorth the position.
65 * @return The point for that position.
66 */
67 public MapViewPoint getPointFor(EastNorth eastNorth) {
68 return new MapViewEastNorthPoint(eastNorth);
69 }
70
71 /**
72 * Gets a rectangle representing the whole view area.
73 * @return The rectangle.
74 */
75 public MapViewRectangle getViewArea() {
76 return getForView(0, 0).rectTo(getForView(viewWidth, viewHeight));
77 }
78
79 /**
80 * Gets the center of the view.
81 * @return The center position.
82 */
83 public MapViewPoint getCenter() {
84 return getForView(viewWidth / 2.0, viewHeight / 2.0);
85 }
86
87 /**
88 * Gets the width of the view on the Screen;
89 * @return The width of the view component in screen pixel.
90 */
91 public double getViewWidth() {
92 return viewWidth;
93 }
94
95 /**
96 * Gets the height of the view on the Screen;
97 * @return The height of the view component in screen pixel.
98 */
99 public double getViewHeight() {
100 return viewHeight;
101 }
102
103 /**
104 * Gets the current projection used for the MapView.
105 * @return The projection.
106 */
107 public Projection getProjection() {
108 return projection;
109 }
110
111 /**
112 * A class representing a point in the map view. It allows to convert between the different coordinate systems.
113 * @author Michael Zangl
114 */
115 public abstract class MapViewPoint {
116
117 /**
118 * Get this point in view coordinates.
119 * @return The point in view coordinates.
120 */
121 public Point2D getInView() {
122 return new Point2D.Double(getInViewX(), getInViewY());
123 }
124
125 protected abstract double getInViewX();
126
127 protected abstract double getInViewY();
128
129 /**
130 * Convert this point to window coordinates.
131 * @return The point in window coordinates.
132 */
133 public Point2D getInWindow() {
134 Point corner = SwingUtilities.convertPoint(navigatableComponent, new Point(0, 0), null);
135 return getUsingCorner(corner);
136 }
137
138 /**
139 * Convert this point to screen coordinates.
140 * @return The point in screen coordinates.
141 */
142 public Point2D getOnScreen() {
143 Point corner = new Point(0, 0);
144 SwingUtilities.convertPointToScreen(corner, navigatableComponent);
145 return getUsingCorner(corner);
146 }
147
148 private Double getUsingCorner(Point corner) {
149 return new Point2D.Double(corner.getX() + getInViewX(), corner.getY() + getInViewY());
150 }
151
152 /**
153 * Gets the {@link EastNorth} coordinate of this point.
154 * @return The east/north coordinate.
155 */
156 public EastNorth getEastNorth() {
157 return new EastNorth(topLeft.east() + getInViewX() * scale, topLeft.north() - getInViewY() * scale);
158 }
159
160 /**
161 * Create a rectangle from this to the other point.
162 * @param other The other point. Needs to be of the same {@link MapViewState}
163 * @return A rectangle.
164 */
165 public MapViewRectangle rectTo(MapViewPoint other) {
166 return new MapViewRectangle(this, other);
167 }
168
169 /**
170 * Gets the current position in LatLon coordinates according to the current projection.
171 * @return The positon as LatLon.
172 */
173 public LatLon getLatLon() {
174 return projection.eastNorth2latlon(getEastNorth());
175 }
176 }
177
178 private class MapViewViewPoint extends MapViewPoint {
179 private final double x;
180 private final double y;
181
182 MapViewViewPoint(double x, double y) {
183 this.x = x;
184 this.y = y;
185 }
186
187 @Override
188 protected double getInViewX() {
189 return x;
190 }
191
192 @Override
193 protected double getInViewY() {
194 return y;
195 }
196
197 @Override
198 public String toString() {
199 return "MapViewViewPoint [x=" + x + ", y=" + y + "]";
200 }
201 }
202
203 private class MapViewEastNorthPoint extends MapViewPoint {
204
205 private final EastNorth eastNorth;
206
207 MapViewEastNorthPoint(EastNorth eastNorth) {
208 this.eastNorth = eastNorth;
209 }
210
211 @Override
212 protected double getInViewX() {
213 return (eastNorth.east() - topLeft.east()) / scale;
214 }
215
216 @Override
217 protected double getInViewY() {
218 return (topLeft.north() - eastNorth.north()) / scale;
219 }
220
221 @Override
222 public EastNorth getEastNorth() {
223 return eastNorth;
224 }
225
226 @Override
227 public String toString() {
228 return "MapViewEastNorthPoint [eastNorth=" + eastNorth + "]";
229 }
230 }
231
232 /**
233 * A rectangle on the MapView. It is rectangular in screen / EastNorth space.
234 * @author Michael Zangl
235 */
236 public class MapViewRectangle {
237 private final MapViewPoint p1;
238 private final MapViewPoint p2;
239
240 /**
241 * Create a new MapViewRectangle
242 * @param p1 The first point to use
243 * @param p2 The second point to use.
244 */
245 MapViewRectangle(MapViewPoint p1, MapViewPoint p2) {
246 this.p1 = p1;
247 this.p2 = p2;
248 }
249
250 /**
251 * Gets the projection bounds for this rectangle.
252 * @return The projection bounds.
253 */
254 public ProjectionBounds getProjectionBounds() {
255 ProjectionBounds b = new ProjectionBounds(p1.getEastNorth());
256 b.extend(p2.getEastNorth());
257 return b;
258 }
259
260 /**
261 * Gets a rough estimate of the bounds by assuming lat/lon are parallel to x/y.
262 * @return The bounds computed by converting the corners of this rectangle.
263 */
264 public Bounds getCornerBounds() {
265 Bounds b = new Bounds(p1.getLatLon());
266 b.extend(p2.getLatLon());
267 return b;
268 }
269 }
270}
Note: See TracBrowser for help on using the repository browser.