package org.osmdroid.tileprovider.modules;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import org.osmdroid.api.IMapView;
/**
* supports raster imagery in the MBTiles 1.1 spec
https://sourceforge.net/p/mobac/code/HEAD/tree/trunk/MOBAC/src/main/java/mobac/program/atlascreators/MBTiles.java
https://github.com/mapbox/mbtiles-spec/tree/master/1.1
@author neilboyd circa 2011
*/
public class MBTilesFileArchive implements IArchiveFile {
private SQLiteDatabase mDatabase;
public MBTilesFileArchive(){}
// TABLE tiles (zoom_level INTEGER, tile_column INTEGER, tile_row INTEGER, tile_data BLOB);
public final static String TABLE_TILES = "tiles";
public final static String COL_TILES_ZOOM_LEVEL = "zoom_level";
public final static String COL_TILES_TILE_COLUMN = "tile_column";
public final static String COL_TILES_TILE_ROW = "tile_row";
public final static String COL_TILES_TILE_DATA = "tile_data";
private MBTilesFileArchive(final SQLiteDatabase pDatabase) {
mDatabase = pDatabase;
}
public static MBTilesFileArchive getDatabaseFileArchive(final File pFile) throws SQLiteException {
return new MBTilesFileArchive(
SQLiteDatabase.openDatabase(
pFile.getAbsolutePath(),
null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY));
}
@Override
public void init(File pFile) throws Exception {
mDatabase=SQLiteDatabase.openDatabase(
pFile.getAbsolutePath(),
null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY);
}
@Override
public InputStream getInputStream(final ITileSource pTileSource, final MapTile pTile) {
try {
InputStream ret = null;
final String[] tile = { COL_TILES_TILE_DATA };
final String[] xyz = {
Integer.toString(pTile.getX())
, Double.toString(Math.pow(2, pTile.getZoomLevel()) - pTile.getY() - 1) // Use Google Tiling Spec
, Integer.toString(pTile.getZoomLevel())
};
final Cursor cur = mDatabase.query(TABLE_TILES, tile, "tile_column=? and tile_row=? and zoom_level=?", xyz, null, null, null);
if(cur.getCount() != 0) {
cur.moveToFirst();
ret = new ByteArrayInputStream(cur.getBlob(0));
}
cur.close();
if(ret != null) {
return ret;
}
} catch(final Throwable e) {
Log.w(IMapView.LOGTAG,"Error getting db stream: " + pTile, e);
}
return null;
}
public Set<String> getTileSources(){
//the MBTiles spec doesn't store source information in it, so we can't return anything
return Collections.EMPTY_SET;
}
@Override
public void close() {
mDatabase.close();
}
@Override
public String toString() {
return "DatabaseFileArchive [mDatabase=" + mDatabase.getPath() + "]";
}
}