当我在osmdroid MapView中使用离线地图数据时,渲染速度非常慢

时间:2013-08-12 08:55:40

标签: android osmdroid

我的离线地图数据源格式是MBTiles。数据库有2个表: Table1名称是存储数据的首选项,如: 名称,值

表2名称是存储数据的图块,如:

tileKey,缩放,行,列,图像

然后我创建一个类

公共类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;

}

}

它可以很好地显示离线地图。只有一个问题是:渲染速度非常慢

有什么建议吗? 感谢。

2 个答案:

答案 0 :(得分:1)

您不想扩展BitmapTileSourceBase。您想要创建一个包含MapTileFileArchiveProvider和您自己的IArchiveFile的切片提供程序链。有关支持数据库IArchiveFile的示例,请参阅DatabaseFileArchive.java

如果您仍然遇到速度问题,您应该运行探查器以查看减速的位置。

答案 1 :(得分:0)

你的mbtiles文件上有任何索引吗? Kurtzmarc的答案会起作用,但这条路走得很乱。我已经开始工作,性能还可以,但我想要一个更清洁的解决方案。我想从XYTileSource开始并从那里继续前进。