]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/gui/map/MapTileManager.java
Version 14, October 2012
[GpsPrune.git] / tim / prune / gui / map / MapTileManager.java
index 9f1fbfe70f8ccde2ca78d87240dc48fb51ef923a..75f170a20f57df5ec5e84d3a2afa904a66d247e1 100644 (file)
@@ -1,7 +1,6 @@
 package tim.prune.gui.map;
 
 import java.awt.Image;
-import java.awt.Toolkit;
 import java.awt.image.ImageObserver;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -24,6 +23,8 @@ public class MapTileManager implements ImageObserver
        private int _numLayers = -1;
        /** Current zoom level */
        private int _zoom = 0;
+       /** Number of tiles in each direction for this zoom level */
+       private int _numTileIndices = 1;
 
 
        /**
@@ -33,6 +34,8 @@ public class MapTileManager implements ImageObserver
        public MapTileManager(MapCanvas inParent)
        {
                _parent = inParent;
+               // Adjust the index of the selected map source
+               adjustSelectedMap();
                resetConfig();
        }
 
@@ -45,6 +48,8 @@ public class MapTileManager implements ImageObserver
        public void centreMap(int inZoom, int inTileX, int inTileY)
        {
                _zoom = inZoom;
+               // Calculate number of tiles = 2^^zoom
+               _numTileIndices = 1 << _zoom;
                // Pass params onto all memory cachers
                if (_tempCaches != null) {
                        for (int i=0; i<_tempCaches.length; i++) {
@@ -69,8 +74,9 @@ public class MapTileManager implements ImageObserver
        public void clearMemoryCaches()
        {
                int numLayers = _mapSource.getNumLayers();
-               if (_tempCaches == null || _tempCaches.length != numLayers) {
-                       // Ccahers don't match, so need to create the right number of them
+               if (_tempCaches == null || _tempCaches.length != numLayers)
+               {
+                       // Cachers don't match, so need to create the right number of them
                        _tempCaches = new MemTileCacher[numLayers];
                        for (int i=0; i<numLayers; i++) {
                                _tempCaches[i] = new MemTileCacher();
@@ -96,6 +102,26 @@ public class MapTileManager implements ImageObserver
                _numLayers = _mapSource.getNumLayers();
        }
 
+       /**
+        * Adjust the index of the selected map
+        * (only required if config was loaded from a previous version of GpsPrune)
+        */
+       private void adjustSelectedMap()
+       {
+               int sourceNum = Config.getConfigInt(Config.KEY_MAPSOURCE_INDEX);
+               int prevNumFixed = Config.getConfigInt(Config.KEY_NUM_FIXED_MAPS);
+               // Number of fixed maps not specified in version <=13, default to 6
+               if (prevNumFixed == 0) prevNumFixed = 6;
+               int currNumFixed = MapSourceLibrary.getNumFixedSources();
+               // Only need to do something if the number has changed
+               if (currNumFixed != prevNumFixed && (sourceNum >= prevNumFixed || sourceNum >= currNumFixed))
+               {
+                       sourceNum += (currNumFixed - prevNumFixed);
+                       Config.setConfigInt(Config.KEY_MAPSOURCE_INDEX, sourceNum);
+               }
+               Config.setConfigInt(Config.KEY_NUM_FIXED_MAPS, currNumFixed);
+       }
+
        /**
         * @return the number of layers in the map
         */
@@ -112,6 +138,10 @@ public class MapTileManager implements ImageObserver
         */
        public Image getTile(int inLayer, int inX, int inY)
        {
+               if (inY < 0 || inY >= _numTileIndices) return null;
+               // Wrap tile indices which are too big or too small
+               inX = ((inX % _numTileIndices) + _numTileIndices) % _numTileIndices;
+
                // Check first in memory cache for tile
                MemTileCacher tempCache = _tempCaches[inLayer]; // Should probably guard against nulls and array indexes here
                Image tile = tempCache.getTile(inX, inY);
@@ -126,9 +156,10 @@ public class MapTileManager implements ImageObserver
                if (useDisk)
                {
                        tile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), onlineMode);
-                       if (tile != null) {
+                       if (tile != null)
+                       {
                                // Pass tile to memory cache
-                               tempCache.setTile(tile, inX, inY);
+                               tempCache.setTile(tile, inX, inY, _zoom);
                                if (tile.getWidth(this) > 0) {return tile;}
                                return null;
                        }
@@ -139,16 +170,17 @@ public class MapTileManager implements ImageObserver
                        try
                        {
                                URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY));
-                               if (useDisk) {
-                                       // Copy image directly from URL stream to disk cache
-                                       DiskTileCacher.saveTile(tileUrl, diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this);
+                               if (useDisk && DiskTileCacher.saveTile(tileUrl, diskCachePath,
+                                       _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this))
+                               {
+                                       // Image now copied directly from URL stream to disk cache
                                }
-                               else {
+                               else
+                               {
                                        // Load image asynchronously, using observer
-                                       tile = Toolkit.getDefaultToolkit().createImage(tileUrl);
-                                       // Pass to memory cache
-                                       _tempCaches[inLayer].setTile(tile, inX, inY);
-                                       if (tile.getWidth(this) > 0) {return tile;}
+                                       // tile = Toolkit.getDefaultToolkit().createImage(tileUrl);
+                                       // In order to set the http user agent, need to use a TileDownloader instead
+                                       TileDownloader.triggerLoad(this, tileUrl, inLayer, inX, inY, _zoom);
                                }
                        }
                        catch (MalformedURLException urle) {} // ignore
@@ -175,4 +207,26 @@ public class MapTileManager implements ImageObserver
                }
                return !loaded;
        }
+
+       /**
+        * Callback method from TileDownloader to let us know that an image has been loaded
+        * @param inTile Loaded Image object
+        * @param inLayer layer index from 0
+        * @param inX x coordinate of tile
+        * @param inY y coordinate of tile
+        * @param inZoom zoom level of loaded image
+        */
+       public void notifyImageLoaded(Image inTile, int inLayer, int inX, int inY, int inZoom)
+       {
+               if (inTile != null)
+               {
+                       MemTileCacher tempCache = _tempCaches[inLayer]; // Should probably guard against nulls and array indexes here
+                       if (tempCache.getTile(inX, inY) == null)
+                       {
+                               // Check with cache that the zoom level is still valid
+                               tempCache.setTile(inTile, inX, inY, inZoom);
+                               inTile.getWidth(this); // trigger imageUpdate when image is ready
+                       }
+               }
+       }
 }