package com.robert.maps.applib.tileprovider;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.andnav.osm.views.util.StreamUtils;
import android.content.Context;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import com.robert.maps.applib.utils.ICacheProvider;
import com.robert.maps.applib.utils.RException;
import com.robert.maps.applib.utils.SQLiteMapDatabase;
import com.robert.maps.applib.utils.SimpleThreadFactory;
import com.robert.maps.applib.utils.Ut;
public class TileProviderInet extends TileProviderBase {
private ICacheProvider mCacheProvider = null;
private ExecutorService mThreadPool = Executors.newFixedThreadPool(5, new SimpleThreadFactory("TileProviderInet"));
public TileProviderInet(Context ctx, TileURLGeneratorBase gen, final String cacheDatabaseName, MapTileMemCache aTileCache, final Bitmap aLoadingMapTile) throws SQLiteException, RException {
this(ctx, gen, cacheDatabaseName, aTileCache);
mLoadingMapTile = aLoadingMapTile;
}
public TileProviderInet(Context ctx, TileURLGeneratorBase gen, final String cacheDatabaseName, MapTileMemCache aTileCache) throws SQLiteException, RException {
super(ctx);
mTileURLGenerator = gen;
if(aTileCache == null)
mTileCache = new MapTileMemCache();
else
mTileCache = aTileCache;
if(cacheDatabaseName != null) {
final SQLiteMapDatabase cacheDatabase = new SQLiteMapDatabase();
final File folder = Ut.getRMapsMainDir(ctx, "cache");
cacheDatabase.setFile(folder.getAbsolutePath()+"/"+cacheDatabaseName+".sqlitedb");
mCacheProvider = cacheDatabase;
} else {
final File folder = Ut.getRMapsCacheTilesDir(ctx);
mCacheProvider = new FSCacheProvider(folder);
}
}
@Override
public void setHandler(Handler mTileMapHandler) {
super.setHandler(mTileMapHandler);
if(mTileURLGenerator instanceof TileURLGeneratorYANDEXTRAFFIC) {
((TileURLGeneratorYANDEXTRAFFIC) mTileURLGenerator).setCallbackHandler(mTileMapHandler);
}
}
@Override
public void Free() {
mThreadPool.shutdown();
if(mCacheProvider != null)
mCacheProvider.Free();
super.Free();
}
@Override
public void removeTileFromCashe(int x, int y, int z) {
final String tileurl = mTileURLGenerator.Get(x, y, z);
mCacheProvider.deleteTile(tileurl, x, y, z);
removeTile(tileurl);
super.removeTileFromCashe(x, y, z);
}
@Override
public Bitmap getTile(final int x, final int y, final int z) {
final String tileurl = mTileURLGenerator.Get(x, y, z);
if(mReloadTileMode)
mTileCache.removeTile(tileurl);
else {
final Bitmap bmp = mTileCache.getMapTile(tileurl);
if(bmp != null)
return bmp;
}
if (!mThreadPool.isTerminated() && !mThreadPool.isShutdown()) {
if (this.mPending.contains(tileurl))
return super.getTile(x, y, z);
mPending.add(tileurl);
mThreadPool.execute(new Runnable() {
public void run() {
InputStream in = null;
OutputStream out = null;
try {
Ut.i("Downloading Maptile from url: " + tileurl);
byte[] data = null;
if (mCacheProvider != null) {
if(mReloadTileMode)
mCacheProvider.deleteTile(tileurl, x, y, z);
else
data = mCacheProvider.getTile(tileurl, x, y, z);
}
if (data == null) {
Ut.w("FROM INTERNET " + tileurl);
in = new BufferedInputStream(new URL(tileurl).openStream(), StreamUtils.IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, StreamUtils.IO_BUFFER_SIZE);
StreamUtils.copy(in, out);
out.flush();
data = dataStream.toByteArray();
if (mCacheProvider != null)
mCacheProvider.putTile(tileurl, x, y, z, data);
}
if (data != null) {
final Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
mTileCache.putTile(tileurl, bmp);
}
SendMessageSuccess();
} catch (Exception e) {
e.printStackTrace();
SendMessageFail();
} catch (OutOfMemoryError e) {
SendMessageFail();
System.gc();
} finally {
StreamUtils.closeStream(in);
StreamUtils.closeStream(out);
}
mPending.remove(tileurl);
}
});
}
return mLoadingMapTile;
}
@Override
public double getTileLength() {
return mCacheProvider.getTileLenght();
}
}