我的离线地图数据源格式是 MBTiles 。数据库有 2 个表:表 1 名称是存储数据的首选项,例如:名称、值
表 2 名称是存储数据的图块,例如:
tileKey,zoom,row,col,image
然后我创建一个类
公共类 MBTileSource 扩展 BitmapTileSourceBase {
// Log log log log ...
private static final Logger logger = LoggerFactory
.getLogger(MBTileSource.class);
// Database related fields
public final static String TABLE_TILES = "tiles";
public final static String COL_TILES_ZOOM_LEVEL = "zoom";
public final static String COL_TILES_TILE_COLUMN = "col";
public final static String COL_TILES_TILE_ROW = "row";
public final static String COL_TILES_TILE_DATA = "image";
protected SQLiteDatabase database;
protected File archive;
// Reasonable defaults ..
public static final int minZoom = 8;
public static final int maxZoom = 15;
public static final int tileSizePixels = 256;
// Required for the superclass
public static final string resourceId = ResourceProxy.string.offline_mode;
/**
* The reason this constructor is protected is because all parameters,
* except file should be determined from the archive file. Therefore a
* factory method is necessary.
*
* @param minZoom
* @param maxZoom
* @param tileSizePixels
* @param file
*/
protected MBTileSource(int minZoom, int maxZoom, int tileSizePixels,
File file, SQLiteDatabase db) {
super("sqlite", resourceId, minZoom, maxZoom, tileSizePixels, ".png");
archive = file;
database = db;
}
/**
* Creates a new MBTileSource from file.
*
* Parameters minZoom, maxZoom en tileSizePixels are obtained from the
* database. If they cannot be obtained from the DB, the default values as
* defined by this class are used.
*
* @param file
* @return
*/
public static MBTileSource createFromFile(File file) {
SQLiteDatabase db;
int flags = SQLiteDatabase.NO_LOCALIZED_COLLATORS
| SQLiteDatabase.OPEN_READONLY;
// int value;
int minZoomLevel=minZoom;
int maxZoomLevel=maxZoom;
int tileSize = tileSizePixels;
InputStream is = null;
// Open the database
db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, flags);
// Get the minimum zoomlevel from the MBTiles file
Cursor pCursor = db.rawQuery("SELECT * FROM preferences;", null);
try {
if (pCursor.getCount() != 0) {
pCursor.moveToFirst();
do {
String name=pCursor.getString(pCursor.getColumnIndex("name"));
if(name.equalsIgnoreCase("map.minZoom")){
minZoomLevel=pCursor.getInt(pCursor.getColumnIndex("value"));
}else if(name.equalsIgnoreCase("map.maxZoom")){
maxZoomLevel=pCursor.getInt(pCursor.getColumnIndex("value"));
}else if(name.equalsIgnoreCase("map.tileSideLength")){
tileSize=pCursor.getInt(pCursor.getColumnIndex("value"));
}
} while (pCursor.moveToNext());
}
pCursor.close();
} catch (Exception e) {
// TODO: handle exception
}
return new MBTileSource(minZoomLevel, maxZoomLevel, tileSize, file, db);
}
public InputStream getInputStream(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),
Integer.toString(pTile.getZoomLevel()) };
final Cursor cur = database.query(TABLE_TILES, tile,
"col=? and row=? and zoom=?", 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) {
logger.warn("Error getting db stream: " + pTile, e);
}
return null;
}
}
显示离线地图效果很好。只有一个问题:渲染速度真的很慢
有什么建议吗?谢谢。