Changeset 10375 in josm for trunk/src/org/openstreetmap/josm/gui/MapViewState.java
- Timestamp:
- 2016-06-14T19:46:27+02:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/MapViewState.java
r10343 r10375 2 2 package org.openstreetmap.josm.gui; 3 3 4 import java.awt.Container; 4 5 import java.awt.Point; 6 import java.awt.geom.AffineTransform; 5 7 import java.awt.geom.Point2D; 6 8 import java.awt.geom.Point2D.Double; 7 9 8 import javax.swing. SwingUtilities;10 import javax.swing.JComponent; 9 11 10 12 import org.openstreetmap.josm.Main; … … 14 16 import org.openstreetmap.josm.data.coor.LatLon; 15 17 import org.openstreetmap.josm.data.projection.Projection; 18 import org.openstreetmap.josm.gui.download.DownloadDialog; 16 19 17 20 /** … … 20 23 * @since 10343 21 24 */ 22 public class MapViewState {23 24 private final Projection projection = Main.getProjection();25 public final class MapViewState { 26 27 private final Projection projection; 25 28 26 29 private final int viewWidth; … … 34 37 private final EastNorth topLeft; 35 38 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); 39 private final Point topLeftOnScreen; 40 private final Point topLeftInWindow; 41 42 /** 43 * Create a new {@link MapViewState} 44 * @param projection The projection to use. 45 * @param viewWidth The view width 46 * @param viewHeight The view height 47 * @param scale The scale to use 48 * @param topLeft The top left corner in east/north space. 49 */ 50 private MapViewState(Projection projection, int viewWidth, int viewHeight, double scale, EastNorth topLeft) { 51 this.projection = projection; 52 this.scale = scale; 53 this.topLeft = topLeft; 54 55 this.viewWidth = viewWidth; 56 this.viewHeight = viewHeight; 57 topLeftInWindow = new Point(0, 0); 58 topLeftOnScreen = new Point(0, 0); 59 } 60 61 private MapViewState(EastNorth topLeft, MapViewState mapViewState) { 62 this.projection = mapViewState.projection; 63 this.scale = mapViewState.scale; 64 this.topLeft = topLeft; 65 66 viewWidth = mapViewState.viewWidth; 67 viewHeight = mapViewState.viewHeight; 68 topLeftInWindow = mapViewState.topLeftInWindow; 69 topLeftOnScreen = mapViewState.topLeftOnScreen; 70 } 71 72 private MapViewState(double scale, MapViewState mapViewState) { 73 this.projection = mapViewState.projection; 74 this.scale = scale; 75 this.topLeft = mapViewState.topLeft; 76 77 viewWidth = mapViewState.viewWidth; 78 viewHeight = mapViewState.viewHeight; 79 topLeftInWindow = mapViewState.topLeftInWindow; 80 topLeftOnScreen = mapViewState.topLeftOnScreen; 81 } 82 83 private MapViewState(JComponent position, MapViewState mapViewState) { 84 this.projection = mapViewState.projection; 85 this.scale = mapViewState.scale; 86 this.topLeft = mapViewState.topLeft; 87 88 viewWidth = position.getWidth(); 89 viewHeight = position.getHeight(); 90 topLeftInWindow = new Point(); 91 // better than using swing utils, since this allows us to use the mehtod if no screen is present. 92 Container component = position; 93 while (component != null) { 94 topLeftInWindow.x += component.getX(); 95 topLeftInWindow.y += component.getY(); 96 component = component.getParent(); 97 } 98 topLeftOnScreen = position.getLocationOnScreen(); 99 } 100 101 /** 102 * The scale in east/north units per pixel. 103 * @return The scale. 104 */ 105 public double getScale() { 106 return scale; 50 107 } 51 108 … … 110 167 111 168 /** 169 * Creates an affine transform that is used to convert the east/north coordinates to view coordinates. 170 * @return The affine transform. It should not be changed. 171 * @since xxx 172 */ 173 public AffineTransform getAffineTransform() { 174 return new AffineTransform(1.0 / scale, 0.0, 0.0, -1.0 / scale, topLeft.east() / scale, 175 topLeft.north() / scale); 176 } 177 178 /** 179 * Creates a new state that is the same as the current state except for that it is using a new center. 180 * @param newCenter The new center coordinate. 181 * @return The new state. 182 * @since xxx 183 */ 184 public MapViewState usingCenter(EastNorth newCenter) { 185 return movedTo(getCenter(), newCenter); 186 } 187 188 /** 189 * @param mapViewPoint The reference point. 190 * @param newEastNorthThere The east/north coordinate that should be there. 191 * @return The new state. 192 * @since xxx 193 */ 194 public MapViewState movedTo(MapViewPoint mapViewPoint, EastNorth newEastNorthThere) { 195 EastNorth delta = newEastNorthThere.subtract(mapViewPoint.getEastNorth()); 196 if (delta.distanceSq(0, 0) < .000001) { 197 return this; 198 } else { 199 return new MapViewState(topLeft.add(delta), this); 200 } 201 } 202 203 /** 204 * Creates a new state that is the same as the current state except for that it is using a new scale. 205 * @param newScale The new scale to use. 206 * @return The new state. 207 * @since xxx 208 */ 209 public MapViewState usingScale(double newScale) { 210 return new MapViewState(newScale, this); 211 } 212 213 /** 214 * Creates a new state that is the same as the current state except for that it is using the location of the given component. 215 * <p> 216 * The view is moved so that the center is the same as the old center. 217 * @param positon The new location to use. 218 * @return The new state. 219 * @since xxx 220 */ 221 public MapViewState usingLocation(JComponent positon) { 222 EastNorth center = this.getCenter().getEastNorth(); 223 return new MapViewState(positon, this).usingCenter(center); 224 } 225 226 /** 227 * Create the default {@link MapViewState} object for the given map view. The screen position won't be set so that this method can be used 228 * before the view was added to the hirarchy. 229 * @param width The view width 230 * @param height The view height 231 * @return The state 232 * @since xxx 233 */ 234 public static MapViewState createDefaultState(int width, int height) { 235 Projection projection = Main.getProjection(); 236 double scale = projection.getDefaultZoomInPPD(); 237 MapViewState state = new MapViewState(projection, width, height, scale, new EastNorth(0, 0)); 238 EastNorth center = calculateDefaultCenter(); 239 return state.movedTo(state.getCenter(), center); 240 } 241 242 private static EastNorth calculateDefaultCenter() { 243 Bounds b = DownloadDialog.getSavedDownloadBounds(); 244 if (b == null) { 245 b = Main.getProjection().getWorldBoundsLatLon(); 246 } 247 return Main.getProjection().latlon2eastNorth(b.getCenter()); 248 } 249 250 /** 112 251 * A class representing a point in the map view. It allows to convert between the different coordinate systems. 113 252 * @author Michael Zangl … … 132 271 */ 133 272 public Point2D getInWindow() { 134 Point corner = SwingUtilities.convertPoint(navigatableComponent, new Point(0, 0), null); 135 return getUsingCorner(corner); 273 return getUsingCorner(topLeftInWindow); 136 274 } 137 275 … … 141 279 */ 142 280 public Point2D getOnScreen() { 143 Point corner = new Point(0, 0); 144 SwingUtilities.convertPointToScreen(corner, navigatableComponent); 145 return getUsingCorner(corner); 281 return getUsingCorner(topLeftOnScreen); 146 282 } 147 283 … … 268 404 } 269 405 } 406 270 407 }
Note:
See TracChangeset
for help on using the changeset viewer.