package com.mutu.mapapi.tileprovider.tilesource;
import java.io.File;
import java.io.InputStream;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mutu.mapapi.ResourceProxy;
import com.mutu.mapapi.ResourceProxy.string;
import com.mutu.mapapi.tileprovider.BitmapPool;
import com.mutu.mapapi.tileprovider.ExpirableBitmapDrawable;
import com.mutu.mapapi.tileprovider.MapTile;
import com.mutu.mapapi.tileprovider.ReusableBitmapDrawable;
import com.mutu.mapapi.tileprovider.constants.OpenStreetMapTileProviderConstants;
import com.mutu.mapapi.tilesystem.TileSystem;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
public abstract class BitmapTileSourceBase implements ITileSource,
OpenStreetMapTileProviderConstants {
private static final Logger logger = LoggerFactory.getLogger(BitmapTileSourceBase.class);
private static int globalOrdinal = 0;
private final int mMinimumZoomLevel;
private final int mMaximumZoomLevel;
private final int mOrdinal;
protected final String mName;
protected final String mImageFilenameEnding;
protected final Random random = new Random();
private final int mTileSizePixels;
private final TileSystem mTileSystem;
private final string mResourceId;
public BitmapTileSourceBase(final String aName, final string aResourceId,
final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels,
final TileSystem aTileSystem,
final String aImageFilenameEnding) {
mResourceId = aResourceId;
mOrdinal = globalOrdinal++;
mName = aName;
mMinimumZoomLevel = aZoomMinLevel;
mMaximumZoomLevel = aZoomMaxLevel;
mTileSizePixels = aTileSizePixels;
mTileSystem = aTileSystem;
mTileSystem.setTileSize(aTileSizePixels);
mImageFilenameEnding = aImageFilenameEnding;
}
@Override
public int ordinal() {
return mOrdinal;
}
@Override
public String name() {
return mName;
}
public String pathBase() {
return mName;
}
public String imageFilenameEnding() {
return mImageFilenameEnding;
}
@Override
public int getMinimumZoomLevel() {
return mMinimumZoomLevel;
}
@Override
public int getMaximumZoomLevel() {
return mMaximumZoomLevel;
}
@Override
public int getTileSizePixels() {
return mTileSizePixels;
}
@Override
public TileSystem getTileSystem(){
return mTileSystem;
}
@Override
public String localizedName(final ResourceProxy proxy) {
return proxy.getString(mResourceId);
}
@Override
public Drawable getDrawable(final String aFilePath) {
try {
// default implementation will load the file as a bitmap and create
// a BitmapDrawable from it
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
BitmapPool.getInstance().applyReusableOptions(bitmapOptions);
final Bitmap bitmap = BitmapFactory.decodeFile(aFilePath, bitmapOptions);
if (bitmap != null) {
return new ReusableBitmapDrawable(bitmap);
} else {
// if we couldn't load it then it's invalid - delete it
try {
new File(aFilePath).delete();
} catch (final Throwable e) {
logger.error("Error deleting invalid file: " + aFilePath, e);
}
}
} catch (final OutOfMemoryError e) {
logger.error("OutOfMemoryError loading bitmap: " + aFilePath);
System.gc();
}
return null;
}
@Override
public String getTileRelativeFilenameString(final MapTile tile) {
final StringBuilder sb = new StringBuilder();
sb.append(pathBase());
sb.append('/');
sb.append(tile.getZoomLevel());
sb.append('/');
sb.append(tile.getX());
sb.append('/');
sb.append(tile.getY());
sb.append(imageFilenameEnding());
return sb.toString();
}
@Override
public Drawable getDrawable(final InputStream aFileInputStream) throws LowMemoryException {
try {
// default implementation will load the file as a bitmap and create
// a BitmapDrawable from it
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
BitmapPool.getInstance().applyReusableOptions(bitmapOptions);
final Bitmap bitmap = BitmapFactory.decodeStream(aFileInputStream, null, bitmapOptions);
if (bitmap != null) {
return new ReusableBitmapDrawable(bitmap);
}
} catch (final OutOfMemoryError e) {
logger.error("OutOfMemoryError loading bitmap");
System.gc();
throw new LowMemoryException(e);
}
return null;
}
public final class LowMemoryException extends Exception {
private static final long serialVersionUID = 146526524087765134L;
public LowMemoryException(final String pDetailMessage) {
super(pDetailMessage);
}
public LowMemoryException(final Throwable pThrowable) {
super(pThrowable);
}
}
}