/*
* 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.core.model.Tile;
import android.graphics.Bitmap;
import android.util.Log;
/**
* A MapWorker uses a {@link MapGenerator} 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 TileCache fileSystemTileCache;
private TileCache inMemoryTileCache;
private JobQueue jobQueue;
private MapGenerator mapGenerator;
private MapView mapView;
private 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 mapGenerator
* the MapGenerator which this MapWorker should use.
*/
public void setMapGenerator(MapGenerator mapGenerator) {
this.mapGenerator = mapGenerator;
}
@Override
protected void afterRun() {
this.mapView = null;
this.mapGenerator = null;
this.fileSystemTileCache = null;
this.inMemoryTileCache = null;
this.jobQueue = null;
this.tileBitmap.recycle();
this.tileBitmap = null;
}
@Override
protected void doWork() {
MapGeneratorJob mapGeneratorJob = this.jobQueue.poll();
if (this.inMemoryTileCache.containsKey(mapGeneratorJob)) {
return;
} else if (this.fileSystemTileCache.containsKey(mapGeneratorJob)) {
return;
}
boolean success;
try {
success = this.mapGenerator.executeJob(mapGeneratorJob, this.tileBitmap);
} catch (Exception e) {
Log.e(THREAD_NAME, "Error with tile: " + this.tileBitmap + ": " + e.getLocalizedMessage());
success = false;
}
if (!isInterrupted() && success) {
if (this.mapView.getFrameBuffer().drawBitmap(mapGeneratorJob.tile, this.tileBitmap)) {
this.inMemoryTileCache.put(mapGeneratorJob, this.tileBitmap);
}
this.mapView.postInvalidate();
this.fileSystemTileCache.put(mapGeneratorJob, this.tileBitmap);
}
}
@Override
protected String getThreadName() {
return THREAD_NAME;
}
@Override
protected int getThreadPriority() {
return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
}
@Override
protected boolean hasWork() {
return !this.jobQueue.isEmpty();
}
}