Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

Add mbtiles tilesource in vtm-android #59

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.oscim.android.tiling.source.mbtiles;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import org.oscim.layers.tile.MapTile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.source.ITileDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
* Created by chaohan on 14-4-3.
*/
public class MBTileDataSource implements ITileDataSource {

static final Logger log = LoggerFactory.getLogger(MBTileDataSource.class);

MBTileSource mMBTileSource;
ITileDecoder mTileDecoder;

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";

public MBTileDataSource(MBTileSource tileSource, ITileDecoder tileDecoder){
mMBTileSource = tileSource;
mTileDecoder = tileDecoder;
}

public void query(MapTile tile, ITileDataSink sink){


try {
InputStream ret = null;
final String[] tiledata = { COL_TILES_TILE_DATA };
final String[] xyz = {
Integer.toString(tile.tileX)
, Double.toString(Math.pow(2, tile.zoomLevel) - tile.tileY - 1) // Use Google Tiling Spec
, Integer.toString(tile.zoomLevel)
};

final Cursor cur = mMBTileSource.db.query(TABLE_TILES, tiledata, "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) {
if (mTileDecoder.decode(tile, sink, ret)) {
sink.completed(ITileDataSink.QueryResult.SUCCESS);
return;
}
}
} catch(final Throwable e) {
log.warn("Error getting db stream: " + tile, e);
sink.completed(ITileDataSink.QueryResult.FAILED);
}
sink.completed(ITileDataSink.QueryResult.FAILED);

}

public void destroy(){

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.oscim.android.tiling.source.mbtiles;

import android.database.sqlite.SQLiteDatabase;

import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.TileSource;
import org.oscim.tiling.source.ITileDecoder;
import org.oscim.tiling.source.bitmap.BitmapTileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
* Created by chaohan on 14-4-3.
*/
public class MBTileSource extends TileSource {
static final Logger log = LoggerFactory.getLogger(MBTileSource.class);

SQLiteDatabase db;


public ITileDataSource getDataSource(){
return new MBTileDataSource(this, new BitmapTileDecoder());
}

public boolean setFile(String filename) {
setOption("file", filename);

File file = new File(filename);

if (!file.exists()) {
return false;
} else if (!file.isFile()) {
return false;
} else if (!file.canRead()) {
return false;
}

return true;
}

public OpenResult open(){
if (!options.containsKey("file"))
return new OpenResult("no mb file set");

try {
// make sure to close any previously opened file first
//close();

File file = new File(options.get("file"));

// check if the file exists and is readable
if (!file.exists()) {
return new OpenResult("file does not exist: " + file);
} else if (!file.isFile()) {
return new OpenResult("not a file: " + file);
} else if (!file.canRead()) {
return new OpenResult("cannot read file: " + file);
}

// open the file in read only mode
db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY);

return OpenResult.SUCCESS;
} catch (Exception e) {
log.error(e.getMessage());
// make sure that the file is closed
close();
return new OpenResult(e.getMessage());
}
}

public void close(){
if (db != null)
db.close();
}

public class BitmapTileDecoder implements ITileDecoder {

@Override
public boolean decode(Tile tile, ITileDataSink sink, InputStream is)
throws IOException {

Bitmap bitmap = CanvasAdapter.g.decodeBitmap(is);
if (!bitmap.isValid()) {
log.debug("{} invalid bitmap", tile);
return false;
}
sink.setTileImage(bitmap);

return true;
}
}
}