利用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); } } }