1 package tim.prune.gui.map;
4 import java.awt.Toolkit;
5 import java.awt.image.ImageObserver;
6 import java.net.MalformedURLException;
9 import tim.prune.config.Config;
12 * Class responsible for managing the map tiles,
13 * including invoking the correct memory cacher(s) and/or disk cacher(s)
15 public class MapTileManager implements ImageObserver
17 /** Parent object to inform when tiles received */
18 private MapCanvas _parent = null;
19 /** Current map source */
20 private MapSource _mapSource = null;
21 /** Array of tile caches, one per layer */
22 private MemTileCacher[] _tempCaches = null;
23 /** Number of layers */
24 private int _numLayers = -1;
25 /** Current zoom level */
26 private int _zoom = 0;
31 * @param inParent parent canvas to be informed of updates
33 public MapTileManager(MapCanvas inParent)
41 * @param inZoom zoom level
42 * @param inTileX x coord of central tile
43 * @param inTileY y coord of central tile
45 public void centreMap(int inZoom, int inTileX, int inTileY)
48 // Pass params onto all memory cachers
49 if (_tempCaches != null) {
50 for (int i=0; i<_tempCaches.length; i++) {
51 _tempCaches[i].centreMap(inZoom, inTileX, inTileY);
57 * @return true if zoom is too high for tiles
59 public boolean isOverzoomed()
61 // Ask current map source what maximum zoom is
62 int maxZoom = (_mapSource == null?0:_mapSource.getMaxZoomLevel());
63 return (_zoom > maxZoom);
67 * Clear all the memory caches due to changed config / zoom
69 public void clearMemoryCaches()
71 int numLayers = _mapSource.getNumLayers();
72 if (_tempCaches == null || _tempCaches.length != numLayers) {
73 // Ccahers don't match, so need to create the right number of them
74 _tempCaches = new MemTileCacher[numLayers];
75 for (int i=0; i<numLayers; i++) {
76 _tempCaches[i] = new MemTileCacher();
80 // Cachers already there, just need to be cleared
81 for (int i=0; i<numLayers; i++) {
82 _tempCaches[i].clearAll();
88 * Reset the map source configuration, apparently it has changed
90 public void resetConfig()
92 int sourceNum = Config.getConfigInt(Config.KEY_MAPSOURCE_INDEX);
93 _mapSource = MapSourceLibrary.getSource(sourceNum);
94 if (_mapSource == null) {_mapSource = MapSourceLibrary.getSource(0);}
96 _numLayers = _mapSource.getNumLayers();
100 * @return the number of layers in the map
102 public int getNumLayers()
108 * @param inLayer layer number, starting from 0
109 * @param inX x index of tile
110 * @param inY y index of tile
111 * @return selected tile if already loaded, or null otherwise
113 public Image getTile(int inLayer, int inX, int inY)
115 // Check first in memory cache for tile
116 MemTileCacher tempCache = _tempCaches[inLayer]; // Should probably guard against nulls and array indexes here
117 Image tile = tempCache.getTile(inX, inY);
122 // Tile wasn't in memory, but maybe it's in disk cache (if there is one)
123 String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
124 boolean useDisk = (diskCachePath != null);
125 boolean onlineMode = Config.getConfigBoolean(Config.KEY_ONLINE_MODE);
128 tile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), onlineMode);
131 // Pass tile to memory cache
132 tempCache.setTile(tile, inX, inY);
133 if (tile.getWidth(this) > 0) {return tile;}
137 // Tile wasn't in memory or on disk, so if online let's get it
142 URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY));
143 if (useDisk && DiskTileCacher.saveTile(tileUrl, diskCachePath,
144 _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this))
146 // Image now copied directly from URL stream to disk cache
150 // Load image asynchronously, using observer
151 tile = Toolkit.getDefaultToolkit().createImage(tileUrl);
152 // Pass to memory cache
153 _tempCaches[inLayer].setTile(tile, inX, inY);
154 if (tile.getWidth(this) > 0) {return tile;}
157 catch (MalformedURLException urle) {} // ignore
163 * Method called by image loader to inform of updates to the tiles
164 * @param img the image
165 * @param infoflags flags describing how much of the image is known
168 * @param width ignored
169 * @param height ignored
170 * @return false to carry on loading, true to stop
172 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
174 boolean loaded = (infoflags & ImageObserver.ALLBITS) > 0;
175 boolean error = (infoflags & ImageObserver.ERROR) > 0;
176 if (loaded || error) {
177 _parent.tilesUpdated(loaded);