0

我的离线地图数据源格式是 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;

}

}

显示离线地图效果很好。只有一个问题:渲染速度真的很慢

有什么建议吗?谢谢。

4

2 回答 2

1

你不想扩展BitmapTileSourceBase. 您想创建一个包含 aMapTileFileArchiveProvider和您自己的IArchiveFile. 有关数据库支持的示例,请参见 DatabaseFileArchive.java IArchiveFile

如果您仍然有速度问题,您应该运行分析器以查看减速的位置。

于 2013-08-12T12:29:59.053 回答
0

你的mbtiles文件有索引吗?Kurtzmarc 的答案会奏效,但走这条路是一团糟。我已经让它工作并且性能还可以,但我想要一个更清洁的解决方案。我正在考虑从 XYTileSource 开始并从那里继续前进。

于 2013-10-10T19:55:06.550 回答