001package org.openstreetmap.gui.jmapviewer;
002
003import org.openstreetmap.gui.jmapviewer.JobDispatcher.JobThread;
004import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
005import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
006import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
007import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
008import org.openstreetmap.gui.jmapviewer.tilesources.OsmTileSource;
009
010public class TileController {
011    protected TileLoader tileLoader;
012    protected TileCache tileCache;
013    protected TileSource tileSource;
014
015    JobDispatcher jobDispatcher;
016
017    public TileController(TileSource source, TileCache tileCache, TileLoaderListener listener) {
018        tileSource = new OsmTileSource.Mapnik();
019        tileLoader = new OsmTileLoader(listener);
020        this.tileCache = tileCache;
021        jobDispatcher = JobDispatcher.getInstance();
022    }
023
024    /**
025     * retrieves a tile from the cache. If the tile is not present in the cache
026     * a load job is added to the working queue of {@link JobThread}.
027     *
028     * @param tilex the X position of the tile
029     * @param tiley the Y position of the tile
030     * @param zoom the zoom level of the tile
031     * @return specified tile from the cache or <code>null</code> if the tile
032     *         was not found in the cache.
033     */
034    public Tile getTile(int tilex, int tiley, int zoom) {
035        int max = (1 << zoom);
036        if (tilex < 0 || tilex >= max || tiley < 0 || tiley >= max)
037            return null;
038        Tile tile = tileCache.getTile(tileSource, tilex, tiley, zoom);
039        if (tile == null) {
040            tile = new Tile(tileSource, tilex, tiley, zoom);
041            tileCache.addTile(tile);
042            tile.loadPlaceholderFromCache(tileCache);
043        }
044        if (tile.error) {
045            tile.loadPlaceholderFromCache(tileCache);
046        }
047        if (!tile.isLoaded()) {
048            jobDispatcher.addJob(tileLoader.createTileLoaderJob(tile));
049        }
050        return tile;
051    }
052
053    public TileCache getTileCache() {
054        return tileCache;
055    }
056
057    public void setTileCache(TileCache tileCache) {
058        this.tileCache = tileCache;
059    }
060
061    public TileLoader getTileLoader() {
062        return tileLoader;
063    }
064
065    public void setTileLoader(TileLoader tileLoader) {
066        this.tileLoader = tileLoader;
067    }
068
069    public TileSource getTileLayerSource() {
070        return tileSource;
071    }
072
073    public TileSource getTileSource() {
074        return tileSource;
075    }
076
077    public void setTileSource(TileSource tileSource) {
078        this.tileSource = tileSource;
079    }
080
081    /**
082     *
083     */
084    public void cancelOutstandingJobs() {
085        jobDispatcher.cancelOutstandingJobs();
086    }
087}