/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.image.BufferedImage; import java.net.ConnectException; import mobac.exceptions.DownloadFailedException; import mobac.gui.mapview.Tile.TileState; import mobac.gui.mapview.interfaces.TileLoaderListener; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import org.apache.log4j.Logger; /** * A {@link TileLoaderJobCreator} implementation that loads tiles from OSM via HTTP and saves all loaded files in a * directory located in the the temporary directory. If a tile is present in this file cache it will not be loaded from * OSM again. * * @author Jan Peter Stotz * @author r_x */ public class TileLoader { private static final Logger log = Logger.getLogger(TileLoader.class); protected TileStore tileStore; protected TileLoaderListener listener; public TileLoader(TileLoaderListener listener) { super(); this.listener = listener; tileStore = TileStore.getInstance(); } public Runnable createTileLoaderJob(final MapSource source, final int tilex, final int tiley, final int zoom) { return new TileAsyncLoadJob(source, tilex, tiley, zoom); } protected class TileAsyncLoadJob implements Runnable { final int tilex, tiley, zoom; final MapSource mapSource; Tile tile; boolean fileTilePainted = false; protected TileStoreEntry tileStoreEntry = null; public TileAsyncLoadJob(MapSource source, int tilex, int tiley, int zoom) { super(); this.mapSource = source; this.tilex = tilex; this.tiley = tiley; this.zoom = zoom; } public void run() { MemoryTileCache cache = listener.getTileImageCache(); synchronized (cache) { tile = cache.getTile(mapSource, tilex, tiley, zoom); if (tile == null || tile.tileState != TileState.TS_NEW) return; tile.setTileState(TileState.TS_LOADING); } if (loadTileFromStore()) return; if (fileTilePainted) { Runnable job = new Runnable() { public void run() { loadOrUpdateTile(); } }; JobDispatcher.getInstance().addJob(job); } else { loadOrUpdateTile(); } } protected void loadOrUpdateTile() { try { BufferedImage image = mapSource.getTileImage(zoom, tilex, tiley, LoadMethod.DEFAULT); if (image != null) { tile.setImage(image); tile.setTileState(TileState.TS_LOADED); listener.tileLoadingFinished(tile, true); } else { tile.setErrorImage(); listener.tileLoadingFinished(tile, false); } return; } catch (ConnectException e) { log.warn("Downloading of " + tile + " failed " + e.getMessage()); } catch (DownloadFailedException e) { log.warn("Downloading of " + tile + " failed " + e.getMessage()); } catch (Exception e) { log.debug("Downloading of " + tile + " failed", e); } tile.setErrorImage(); listener.tileLoadingFinished(tile, false); } protected boolean loadTileFromStore() { try { BufferedImage image = mapSource.getTileImage(zoom, tilex, tiley, LoadMethod.CACHE); if (image == null) return false; tile.setImage(image); listener.tileLoadingFinished(tile, true); if (TileDownLoader.isTileExpired(tileStoreEntry)) return false; fileTilePainted = true; return true; } catch (Exception e) { log.error("Failed to load tile (z=" + zoom + ",x=" + tilex + ",y=" + tiley + ") from tile store", e); } return false; } } }