package com.robert.maps.applib.tileprovider;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.ProgressDialog;
import android.content.Context;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Message;
import com.robert.maps.applib.R;
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 TileProviderSQLITEDB extends TileProviderFileBase {
private ExecutorService mThreadPool = Executors.newSingleThreadExecutor(new SimpleThreadFactory("TileProviderSQLITEDB"));
private SQLiteMapDatabase mUserMapDatabase;
private String mMapID;
private ProgressDialog mProgressDialog;
public TileProviderSQLITEDB(Context ctx, final String filename, final String mapid, MapTileMemCache aTileCache) throws SQLiteException, RException {
super(ctx);
mTileURLGenerator = new TileURLGeneratorBase(filename);
mTileCache = aTileCache == null ? new MapTileMemCache() : aTileCache;
mUserMapDatabase = new SQLiteMapDatabase();
mUserMapDatabase.setFile(filename);
mMapID = mapid;
final File file = new File(filename);
Ut.d("TileProviderSQLITEDB: mapid = "+mapid);
Ut.d("TileProviderSQLITEDB: filename = "+filename);
Ut.d("TileProviderSQLITEDB: file.exists = "+file.exists());
Ut.d("TileProviderSQLITEDB: getRMapsMapsDir = "+Ut.getRMapsMapsDir(ctx));
if(needIndex(mapid, file.length(), file.lastModified(), false)) {
mProgressDialog = Ut.ShowWaitDialog(ctx, R.string.message_updateminmax);
new IndexTask().execute(file.length(), file.lastModified());
}
this.mThreadPool.execute(new Runnable() {
public void run() {
XYZ xyz = null;
Collection<XYZ> col = null;
Iterator<XYZ> it = null;
byte[] data = null;
Bitmap bmp = null;
while(!mThreadPool.isShutdown()) {
synchronized(mPending2) {
col = mPending2.values();
it = col.iterator();
if (it.hasNext())
xyz = it.next();
else
xyz = null;
}
if(xyz == null) {
synchronized(mPending2) {
try {
SendMessageSuccess();
mPending2.wait();
} catch (InterruptedException e) {
}
}
}
else {
data = mUserMapDatabase.getTile(xyz.X, xyz.Y, xyz.Z);
if (data != null) {
try {
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
mTileCache.putTile(xyz.TILEURL, bmp);
} catch (Throwable e) {
e.printStackTrace();
}
}
synchronized(mPending2) {
mPending2.remove(xyz.TILEURL);
}
}
}
}
});
}
public void updateMapParams(TileSource tileSource) {
tileSource.ZOOM_MINLEVEL = ZoomMinInCashFile(mMapID);
tileSource.ZOOM_MAXLEVEL = ZoomMaxInCashFile(mMapID);
}
private class IndexTask extends AsyncTask<Long, Void, Boolean> {
@Override
protected Boolean doInBackground(Long... params) {
try {
final long fileLength = params[0];
Ut.d("IndexTask: fileLength = "+fileLength);
final long fileModified = params[1];
Ut.d("IndexTask: fileModified = "+fileModified);
mUserMapDatabase.updateMinMaxZoom();
Ut.d("IndexTask: mUserMapDatabase.updateMinMaxZoom = OK");
final int minzoom = mUserMapDatabase.getMinZoom();
Ut.d("IndexTask: minzoom = "+minzoom);
final int maxzoom = mUserMapDatabase.getMaxZoom();
Ut.d("IndexTask: maxzoom = "+maxzoom);
CommitIndex(mMapID, fileLength, fileModified, minzoom, maxzoom);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if(result && mCallbackHandler != null)
Message.obtain(mCallbackHandler, MessageHandlerConstants.MAPTILEFSLOADER_INDEXIND_SUCCESS_ID).sendToTarget();
try {
if(mProgressDialog != null)
mProgressDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void Free() {
mThreadPool.shutdown();
synchronized(mPending2) {
mPending2.notify();
}
mUserMapDatabase.Free();
super.Free();
}
private HashMap<String, XYZ> mPending2 = new HashMap<String, XYZ>();
private class XYZ {
public String TILEURL;
public int X;
public int Y;
public int Z;
public XYZ(final String tileurl, final int x, final int y, final int z) {
TILEURL = tileurl;
X = x;
Y = y;
Z = z;
}
}
public Bitmap getTile(final int x, final int y, final int z) {
final String tileurl = mTileURLGenerator.Get(x, y, z);
final Bitmap bmp = mTileCache.getMapTile(tileurl);
if(bmp != null)
return bmp;
synchronized(mPending2) {
if (this.mPending2.containsKey(tileurl))
return mLoadingMapTile;
}
synchronized(mPending2) {
mPending2.put(tileurl, new XYZ(tileurl, x, y, z));
mPending2.notify();
}
return mLoadingMapTile;
}
public int[] findTheMap(int zoomLevel) {
return mUserMapDatabase.findTheMap(zoomLevel);
}
}