/* * Copyright 2010, 2011, 2012 mapsforge.org * * This program is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software * Foundation, either version 3 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package org.mapsforge.android.maps.mapgenerator; import org.mapsforge.android.maps.MapView; import org.mapsforge.android.maps.PausableThread; import org.mapsforge.android.maps.mapgenerator.databaserenderer.DatabaseRenderer; import org.mapsforge.android.maps.mapgenerator.mbtiles.MbTilesDatabaseRenderer; import org.mapsforge.core.model.Tile; import android.graphics.Bitmap; /** * A MapWorker uses a {@link DatabaseRenderer} to generate map tiles. It runs in a separate thread to avoid blocking the * UI thread. */ public class MapWorker extends PausableThread { private static final String THREAD_NAME = "MapWorker"; private MapRenderer mapRenderer; private final TileCache fileSystemTileCache; private final TileCache inMemoryTileCache; private final JobQueue jobQueue; private final MapView mapView; private final Bitmap tileBitmap; /** * @param mapView * the MapView for which this MapWorker generates map tiles. */ public MapWorker(MapView mapView) { super(); this.mapView = mapView; this.jobQueue = mapView.getJobQueue(); this.inMemoryTileCache = mapView.getInMemoryTileCache(); this.fileSystemTileCache = mapView.getFileSystemTileCache(); this.tileBitmap = Bitmap.createBitmap(Tile.TILE_SIZE, Tile.TILE_SIZE, Bitmap.Config.RGB_565); } /** * @param pMapRenderer * the DatabaseRenderer which this MapWorker should use. */ public void setDatabaseRenderer(MapRenderer pMapRenderer) { this.mapRenderer = pMapRenderer; } @Override protected void afterRun() { this.tileBitmap.recycle(); } @Override protected void doWork() { // open the MBTiles DB if necessary if (!this.mapRenderer.isWorking()) { this.mapRenderer.start(); } final boolean usesMBTilesRenderer = this.mapRenderer instanceof MbTilesDatabaseRenderer; MapGeneratorJob mapGeneratorJob = this.jobQueue.poll(); if (this.inMemoryTileCache.containsKey(mapGeneratorJob) && !usesMBTilesRenderer) { return; } else if (this.fileSystemTileCache.containsKey(mapGeneratorJob) && !usesMBTilesRenderer) { return; } boolean success = this.mapRenderer.executeJob(mapGeneratorJob, this.tileBitmap); if (!isInterrupted() && success) { if (this.mapView.getFrameBuffer().drawBitmap(mapGeneratorJob.tile, this.tileBitmap)) { if (!usesMBTilesRenderer) { this.inMemoryTileCache.put(mapGeneratorJob, this.tileBitmap); } } this.mapView.postInvalidate(); if (!usesMBTilesRenderer) { this.fileSystemTileCache.put(mapGeneratorJob, this.tileBitmap); } } // close the MB Tiles DB if queue is empty if (this.jobQueue.isEmpty()) { this.mapRenderer.stop(); } } @Override protected String getThreadName() { return THREAD_NAME; } @Override protected ThreadPriority getThreadPriority() { return ThreadPriority.BELOW_NORMAL; } @Override protected boolean hasWork() { return !this.jobQueue.isEmpty(); } }