1 package tim.prune.gui.map;
4 * Class to hold the current position of the map
6 public class MapPosition
8 /** Width and height of each tile of map */
9 private static final int MAP_TILE_SIZE = 256;
11 /** x position (scale depends on zoom) */
12 private long _xPosition = 0L;
13 /** y position (scale depends on zoom) */
14 private long _yPosition = 0L;
16 /** Zoom level, from 2 to max */
17 private int _zoom = 12;
18 /** Factor to zoom by, 2 to the power of zoom */
19 private int _zoomFactor = 1 << _zoom;
20 /** Maximum zoom level */
21 private static final int MAX_ZOOM = 21;
25 * Zoom and pan to show the selected area
26 * @param inMinX minimum transformed X
27 * @param inMaxX maximum transformed X
28 * @param inMinY minimum transformed Y
29 * @param inMaxY maximum transformed Y
30 * @param inWidth width of display
31 * @param inHeight height of display
33 public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight)
35 // System.out.println("Zooming to " + inMinX + ", " + inMaxX + ", " + inMinY + ", " + inMaxY + "; width=" + inWidth + ", height=" + inHeight);
36 double diffX = Math.abs(inMaxX - inMinX);
37 double diffY = Math.abs(inMaxY - inMinY);
38 // Find out what zoom level to go to
39 int requiredZoom = -1;
40 for (int currZoom = MAX_ZOOM; currZoom >= 2; currZoom--)
42 if (transformToPixels(diffX, currZoom) < inWidth
43 && transformToPixels(diffY, currZoom) < inHeight)
45 requiredZoom = currZoom;
49 if (requiredZoom < 2) requiredZoom = 2;
52 _zoomFactor = 1 << _zoom;
53 _xPosition = transformToPixels((inMinX + inMaxX) / 2.0);
54 _yPosition = transformToPixels((inMinY + inMaxY) / 2.0);
58 * Zoom and pan to show the selected area
59 * @param inMinX minimum pixels X
60 * @param inMaxX maximum pixels X
61 * @param inMinY minimum pixels Y
62 * @param inMaxY maximum pixels Y
63 * @param inWidth width of display
64 * @param inHeight height of display
66 public void zoomToPixels(int inMinX, int inMaxX, int inMinY, int inMaxY, int inWidth, int inHeight)
68 // System.out.println("Current position is " + _xPosition + ", " + _yPosition);
69 int diffX = Math.abs(inMaxX - inMinX);
70 int diffY = Math.abs(inMaxY - inMinY);
71 // Find out what zoom level to go to
72 int requiredZoom = -1;
74 for (int currZoom = MAX_ZOOM; currZoom >= _zoom; currZoom--)
76 multFactor = 1 << (currZoom - _zoom);
77 if ((diffX * multFactor) < inWidth && (diffY * multFactor) < inHeight)
79 requiredZoom = currZoom;
84 _zoomFactor = 1 << _zoom;
86 _xPosition = (_xPosition - inWidth/2 + (inMinX + inMaxX) / 2) * multFactor;
87 _yPosition = (_yPosition - inHeight/2 + (inMinY + inMaxY) / 2) * multFactor;
91 * Transform a given coordinate into pixels using the current zoom value
92 * @param inValue value to transform
95 private long transformToPixels(double inValue)
97 return transformToPixels(inValue, _zoom);
101 * Transform a given coordinate into pixels using the specified zoom value
102 * @param inValue value to transform
103 * @param inZoom zoom value to use
106 private static long transformToPixels(double inValue, int inZoom)
108 return (long) (inValue * MAP_TILE_SIZE * (1 << inZoom));
112 * Convert pixels back into x coordinates
113 * @param inPixelX x coordinate on screen
114 * @param inWidth current width of window
115 * @return x coordinate
117 public double getXFromPixels(int inPixelX, int inWidth)
119 return ((inPixelX - inWidth/2) + _xPosition) * 1.0 / MAP_TILE_SIZE / _zoomFactor;
123 * Convert pixels back into y coordinates
124 * @param inPixelY y coordinate on screen
125 * @param inHeight current height of window
126 * @return y coordinate
128 public double getYFromPixels(int inPixelY, int inHeight)
130 return ((inPixelY - inHeight/2) + _yPosition) * 1.0 / MAP_TILE_SIZE / _zoomFactor;
134 * Get the horizontal offset from the centre
135 * @param inValue value to transform
136 * @return number of pixels right (+ve) or left (-ve) from the centre
138 public int getXFromCentre(double inValue)
140 return (int) (transformToPixels(inValue) - _xPosition);
144 * Get the vertical offset from the centre
145 * @param inValue value to transform
146 * @return number of pixels up (+ve) or down (-ve) from the centre
148 public int getYFromCentre(double inValue)
150 return (int) (transformToPixels(inValue) - _yPosition);
154 * Convert a pixel value into a bounds value for sensitivity
155 * @param inPixels number of pixels
156 * @return bounds value to use for x,y checking
158 public double getBoundsFromPixels(int inPixels) {
159 return (inPixels * 1.0 / MAP_TILE_SIZE / _zoomFactor);
163 * Get the leftmost, rightmost, upper and lower index boundaries for the tiles to display
164 * @param inWidth width of window
165 * @param inHeight height of window
166 * @return tile indices as array left, right, up, down
168 public int[] getTileIndices(int inWidth, int inHeight)
170 int[] result = new int[4];
171 result[0] = getTileIndex(_xPosition - inWidth/2);
172 result[1] = getTileIndex(_xPosition + inWidth/2);
173 result[2] = getTileIndex(_yPosition - inHeight/2);
174 result[3] = getTileIndex(_yPosition + inHeight/2);
179 * Get the pixel offsets for the display
180 * @param inWidth width of window
181 * @param inHeight height of window
182 * @return offsets as x, y
184 public int[] getDisplayOffsets(int inWidth, int inHeight)
186 int[] result = new int[2];
187 result[0] = getDisplayOffset(_xPosition - inWidth/2);
188 result[1] = getDisplayOffset(_yPosition - inHeight/2);
193 * @return x index of the centre tile
195 public int getCentreTileX()
197 return getTileIndex(_xPosition);
201 * @return y index of the centre tile
203 public int getCentreTileY()
205 return getTileIndex(_yPosition);
209 * @param inPosition position of point
210 * @return tile index for that point
212 private int getTileIndex(long inPosition)
214 return (int) (inPosition / MAP_TILE_SIZE);
218 * @param inPosition position of point
219 * @return pixel offset for that point
221 private int getDisplayOffset(long inPosition)
223 return (int) (inPosition % MAP_TILE_SIZE);
224 // Maybe >> 8 would be slightly faster?
232 if (_zoom < MAX_ZOOM)
235 _zoomFactor = 1 << _zoom;
244 public void zoomOut()
249 _zoomFactor = 1 << _zoom;
256 * @return current zoom level
264 * Pan map by the specified amount
265 * @param inDeltaX amount to pan right
266 * @param inDeltaY amount to pan down
268 public void pan(int inDeltaX, int inDeltaY)
270 // TODO: Check bounds?
271 _xPosition += inDeltaX;
272 _yPosition += inDeltaY;