![JAR search and dependency download from the Maven repository](/logo.png)
org.oscim.android.cache.TileCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm-android Show documentation
Show all versions of vtm-android Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 Stephan Leuschner
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
package org.oscim.android.cache;
import android.annotation.TargetApi;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileCache;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
public class TileCache implements ITileCache {
static final org.slf4j.Logger log = LoggerFactory.getLogger(TileCache.class);
static final boolean dbg = false;
class CacheTileReader implements TileReader {
final InputStream mInputStream;
final Tile mTile;
public CacheTileReader(Tile tile, InputStream is) {
mTile = tile;
mInputStream = is;
}
@Override
public Tile getTile() {
return mTile;
}
@Override
public InputStream getInputStream() {
return mInputStream;
}
}
class CacheTileWriter implements TileWriter {
final ByteArrayOutputStream mOutputStream;
final Tile mTile;
CacheTileWriter(Tile tile, ByteArrayOutputStream os) {
mTile = tile;
mOutputStream = os;
}
@Override
public Tile getTile() {
return mTile;
}
@Override
public OutputStream getOutputStream() {
return mOutputStream;
}
@Override
public void complete(boolean success) {
saveTile(mTile, mOutputStream, success);
}
}
private final ArrayList mCacheBuffers;
private final SQLiteHelper dbHelper;
private final SQLiteDatabase mDatabase;
private final SQLiteStatement mStmtGetTile;
private final SQLiteStatement mStmtPutTile;
//private final SQLiteStatement mStmtUpdateTile;
public void dispose() {
if (mDatabase.isOpen())
mDatabase.close();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public TileCache(Context context, String cacheDirectory, String dbName) {
if (dbg)
log.debug("open cache {}, {}", cacheDirectory, dbName);
if (cacheDirectory != null)
dbName = new File(cacheDirectory, dbName).getAbsolutePath();
dbHelper = new SQLiteHelper(context, dbName);
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
dbHelper.setWriteAheadLoggingEnabled(true);
mDatabase = dbHelper.getWritableDatabase();
mStmtGetTile = mDatabase.compileStatement("" +
"SELECT " + COLUMN_DATA +
" FROM " + TABLE_NAME +
" WHERE x=? AND y=? AND z = ?");
mStmtPutTile = mDatabase.compileStatement("" +
"INSERT INTO " + TABLE_NAME +
" (x, y, z, time, last_access, data)" +
" VALUES(?,?,?,?,?,?)");
//mStmtUpdateTile = mDatabase.compileStatement("" +
// "UPDATE " + TABLE_NAME +
// " SET last_access=?" +
// " WHERE x=? AND y=? AND z=?");
mCacheBuffers = new ArrayList();
}
@Override
public TileWriter writeTile(Tile tile) {
ByteArrayOutputStream os;
synchronized (mCacheBuffers) {
if (mCacheBuffers.size() == 0)
os = new ByteArrayOutputStream(32 * 1024);
else
os = mCacheBuffers.remove(mCacheBuffers.size() - 1);
}
return new CacheTileWriter(tile, os);
}
static final String TABLE_NAME = "tiles";
static final String COLUMN_TIME = "time";
static final String COLUMN_ACCESS = "last_access";
static final String COLUMN_DATA = "data";
//static final String COLUMN_SIZE = "size";
class SQLiteHelper extends SQLiteOpenHelper {
//private static final String DATABASE_NAME = "tile.db";
private static final int DATABASE_VERSION = 1;
private static final String TILE_SCHEMA =
"CREATE TABLE "
+ TABLE_NAME + "("
+ "x INTEGER NOT NULL,"
+ "y INTEGER NOT NULL,"
+ "z INTEGER NOT NULL,"
+ COLUMN_TIME + " LONG NOT NULL,"
//+ COLUMN_SIZE + " LONG NOT NULL,"
+ COLUMN_ACCESS + " LONG NOT NULL,"
+ COLUMN_DATA + " BLOB,"
+ "PRIMARY KEY(x,y,z));";
public SQLiteHelper(Context context, String dbName) {
super(context, dbName, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
log.debug("create table");
db.execSQL(TILE_SCHEMA);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
log.debug("drop table");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
public void saveTile(Tile tile, ByteArrayOutputStream data, boolean success) {
byte[] bytes = null;
if (success)
bytes = data.toByteArray();
synchronized (mCacheBuffers) {
data.reset();
mCacheBuffers.add(data);
}
if (dbg)
log.debug("store tile {} {}", tile, Boolean.valueOf(success));
if (!success)
return;
synchronized (mStmtPutTile) {
mStmtPutTile.bindLong(1, tile.tileX);
mStmtPutTile.bindLong(2, tile.tileY);
mStmtPutTile.bindLong(3, tile.zoomLevel);
mStmtPutTile.bindLong(4, 0);
mStmtPutTile.bindLong(5, 0);
mStmtPutTile.bindBlob(6, bytes);
mStmtPutTile.execute();
mStmtPutTile.clearBindings();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public TileReader getTileApi11(Tile tile) {
InputStream in = null;
mStmtGetTile.bindLong(1, tile.tileX);
mStmtGetTile.bindLong(2, tile.tileY);
mStmtGetTile.bindLong(3, tile.zoomLevel);
try {
ParcelFileDescriptor result = mStmtGetTile.simpleQueryForBlobFileDescriptor();
in = new FileInputStream(result.getFileDescriptor());
} catch (SQLiteDoneException e) {
log.debug("not in cache {}", tile);
return null;
} finally {
mStmtGetTile.clearBindings();
}
if (dbg)
log.debug("load tile {}", tile);
return new CacheTileReader(tile, in);
}
private final String[] mQueryVals = new String[3];
@Override
public synchronized TileReader getTile(Tile tile) {
//if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
// return getTileApi11(tile);
mQueryVals[0] = String.valueOf(tile.zoomLevel);
mQueryVals[1] = String.valueOf(tile.tileX);
mQueryVals[2] = String.valueOf(tile.tileY);
Cursor cursor = mDatabase.rawQuery("SELECT " + COLUMN_DATA +
" FROM " + TABLE_NAME +
" WHERE z=? AND x=? AND y=?", mQueryVals);
if (!cursor.moveToFirst()) {
if (dbg)
log.debug("not in cache {}", tile);
cursor.close();
return null;
}
InputStream in = new ByteArrayInputStream(cursor.getBlob(0));
cursor.close();
if (dbg)
log.debug("load tile {}", tile);
return new CacheTileReader(tile, in);
}
@Override
public void setCacheSize(long size) {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy