利用sqlite存储瓦片那是最好不过了,做离线地图的时候,你拷那么多图片慢不?累不?
MBTiles是利用sqlite并有一种规则来存储瓦片的,什么是MBTiles?请参照我的博客; 【移动GIS】MBTiles移动存储简介 这里就不在獒述了。
MBTiles其实就是一个sqlite数据库,但这个数据库按照了一些规则创建了表来存储瓦片信息,所以把它叫做MBTiles,sqlite生成的数据文件的后缀名其实是可以随便改变的哦,不影响你使用的,一般sqlite数据库文件问 .sqlite或者 .db ,然后存储瓦片呢,我们生成数据库文件的时候就把他生成为 .mbtiles格式
在android移动存储过程中,不需要你再额外的加sqlite的JDBC啦,貌似android SDK就支持sqlite,那么如何将瓦片导入到sqlite数据库中呢?没办法,只能自己写个程序然后遍历本地瓦片再依次插入到sqlite中去了,下面贴出插入瓦片的关键代码:
package com.ehl.sqlite;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
/**
* sqlite数据操作
*
* @author fazhen.zheng
*
*/
public class SqliteDB {
private static Statement statement;
private static Connection connection = null;
private static PreparedStatement insertPS = null;
private static PreparedStatement deletePS = null;
public SqliteDB(String mbtilesPath) throws ClassNotFoundException, SQLException{
Class.forName("org.sqlite.JDBC");
if(mbtilesPath==null||mbtilesPath.trim().length()==0){
connection = DriverManager
.getConnection("jdbc:sqlite:ehl_mbtiles_db.mbtiles");
statement = connection.createStatement();
initTable();
}else{
connection = DriverManager.getConnection("jdbc:sqlite:" + mbtilesPath);
statement = connection.createStatement();
}
insertPS = connection.prepareStatement("INSERT INTO tiles (zoom_level,tile_row,tile_column,tile_data) VALUES(?,?,?,?)");
deletePS = connection.prepareStatement("DELETE FROM tiles WHERE zoom_level = ? and tile_row = ? and tile_column = ?");
}
/**
* 初始化表信息
* @throws SQLException
*/
private void initTable() throws SQLException{
statement.execute("DROP TABLE IF EXISTS metadata");
statement.execute("DROP TABLE IF EXISTS tiles");
statement.execute("CREATE TABLE metadata (name text, value text)");
statement.execute("CREATE TABLE tiles (zoom_level integer, tile_row integer, tile_column integer, tile_data blob)");
statement.execute("CREATE UNIQUE INDEX tile_index ON tiles (zoom_level, tile_row, tile_column)");
statement.execute("CREATE UNIQUE INDEX name ON metadata (name)");
statement.execute("INSERT INTO metadata VALUES ('name', 'ehl_mbtiles_db')");
statement.execute("INSERT INTO metadata VALUES ('type', 'baselayer')");
statement.execute("INSERT INTO metadata VALUES ('version', '1.0')");
statement.execute("INSERT INTO metadata VALUES ('description', '移动GIS')");
statement.execute("INSERT INTO metadata VALUES ('format', 'png')");
}
/**
* 插入一条数据
* @param zoom_level
* @param tile_row
* @param tile_column
* @param tile_data
*/
public void insertTiles(String zoom_level, String tile_row,
String tile_column, File tile_data) {
FileInputStream fis;
ByteArrayOutputStream bos = null;
try {
connection.setAutoCommit(false);
fis = new FileInputStream(tile_data);
bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int readNum;
while ((readNum = fis.read(buf)) != -1) {
bos.write(buf, 0, readNum);
}
insertPS.setString(1, zoom_level);
insertPS.setString(2, tile_row);
insertPS.setString(3, tile_column);
insertPS.setBytes(4, bos.toByteArray());
deletePS.setString(1, zoom_level);
deletePS.setString(2, tile_row);
deletePS.setString(3, tile_column);
deletePS.executeUpdate();
insertPS.executeUpdate();
connection.commit();
} catch (Exception e) {
try {
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
/**
* 使用完毕后需关闭一些对象
*/
public void close() {
try {
if (insertPS != null)
insertPS.close();
if (deletePS != null)
deletePS.close();
if(statement!=null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}