From baa7ed3ab6690788f3f3fc961cd47a82a22731ea Mon Sep 17 00:00:00 2001 From: hanchao Date: Thu, 3 Apr 2014 21:51:50 +0800 Subject: [PATCH 1/2] add mbtiles tile source --- .../source/mbtiles/MBTileDataSource.java | 74 +++++++++++++ .../tiling/source/mbtiles/MBTileSource.java | 102 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java create mode 100644 vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileSource.java diff --git a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java new file mode 100644 index 000000000..c019718bf --- /dev/null +++ b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java @@ -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); + + SQLiteDatabase db; + 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){ + db = tileSource.db; + 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 = 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); + } + + + } + + public void destroy(){ + + } +} diff --git a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileSource.java b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileSource.java new file mode 100644 index 000000000..8a445468c --- /dev/null +++ b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileSource.java @@ -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; + } + } +} From 8efd0ee962e928a20cda6fdaad0910247aad5157 Mon Sep 17 00:00:00 2001 From: hanchao Date: Thu, 3 Apr 2014 22:18:27 +0800 Subject: [PATCH 2/2] add mbtiles tile source --- .../android/tiling/source/mbtiles/MBTileDataSource.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java index c019718bf..183c11505 100644 --- a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java +++ b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTileDataSource.java @@ -21,7 +21,7 @@ public class MBTileDataSource implements ITileDataSource { static final Logger log = LoggerFactory.getLogger(MBTileDataSource.class); - SQLiteDatabase db; + MBTileSource mMBTileSource; ITileDecoder mTileDecoder; public final static String TABLE_TILES = "tiles"; @@ -31,7 +31,7 @@ public class MBTileDataSource implements ITileDataSource { public final static String COL_TILES_TILE_DATA = "tile_data"; public MBTileDataSource(MBTileSource tileSource, ITileDecoder tileDecoder){ - db = tileSource.db; + mMBTileSource = tileSource; mTileDecoder = tileDecoder; } @@ -47,7 +47,7 @@ public void query(MapTile tile, ITileDataSink sink){ , Integer.toString(tile.zoomLevel) }; - final Cursor cur = db.query(TABLE_TILES, tiledata, "tile_column=? and tile_row=? and zoom_level=?", xyz, null, null, null); + 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(); @@ -64,7 +64,7 @@ public void query(MapTile tile, ITileDataSink sink){ log.warn("Error getting db stream: " + tile, e); sink.completed(ITileDataSink.QueryResult.FAILED); } - + sink.completed(ITileDataSink.QueryResult.FAILED); }