//********************************************************************** // //<copyright> // //BBN Technologies //10 Moulton Street //Cambridge, MA 02138 //(617) 873-8000 // //Copyright (C) BBNT Solutions LLC. All rights reserved. // //</copyright> //********************************************************************** // //$Source: ///cvs/darwars/ambush/aar/src/com/bbn/ambush/mission/MissionHandler.java,v //$ //$RCSfile: MissionHandler.java,v $ //$Revision: 1.10 $ //$Date: 2004/10/21 20:08:31 $ //$Author: dietrick $ // //********************************************************************** package com.bbn.openmap.dataAccess.mapTile; import java.awt.image.BufferedImage; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; import java.util.logging.Level; import javax.swing.ImageIcon; import com.bbn.openmap.Environment; import com.bbn.openmap.I18n; import com.bbn.openmap.PropertyConsumer; import com.bbn.openmap.image.BufferedImageHelper; import com.bbn.openmap.omGraphics.OMGraphic; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.util.PropUtils; import com.bbn.openmap.util.cacheHandler.CacheObject; /** * The TileMillMapTileFactory is an extension to the StandardMapTileFactory that can read image tiles stored in a * mbtiles file, which is the export format from the TileMill application. The mbtiles file is a sqlite database, so * this factory requires the sqlitejdbc package be used to read those data files. You can find that package at * http://www.zentus.com/sqlitejdbc. * * This component can be configured using properties: <p> * * <pre> * # Inherited from StandardMapTileFactory * rootDir=the jdbc driver/path string to use for the database file, "jdbc:sqlite:path to file" * cacheSize=the number of mapTiles the factory should hold on to. The default is 100. * * #optional: * # The class used to test for the existance of jdbc components. Assumes sqlitejdbc, but the code fetching the tiles * # is pretty standard SQL - so you should be able to use any jdbc driver library. * testClass=org.sqlite.JDBC * * </pre> * * @author dietrick */ public class TileMillMapTileFactory extends StandardMapTileFactory implements MapTileFactory, PropertyConsumer { public final static String DEFAULT_TEST_CLASS = "org.sqlite.JDBC"; public final static String TEST_CLASS_PROPERTY = "testClass"; /** * Test class to use for existence of JDBC drivers. */ protected String testClass = DEFAULT_TEST_CLASS; public TileMillMapTileFactory() { this(null); } public TileMillMapTileFactory(String rootDir) { this.rootDir = rootDir; this.fileExt = ".png"; verbose = logger.isLoggable(Level.FINE); } /** * Fetches a new tile from the database. */ public CacheObject load(Object key, int x, int y, int zoomLevel, Projection proj) { try { Class.forName(testClass); } catch (Exception e) { logger.warning("can't locate sqlite JDBC components"); return null; } try { Connection conn = DriverManager.getConnection(rootDir); Statement stat = conn.createStatement(); //"select zoom_level, tile_column, tile_row, tile_data from map, images where map.tile_id = images.tile_id"; StringBuilder statement = new StringBuilder("select tile_data from map, images where"); statement.append(" zoom_level = ").append(zoomLevel); statement.append(" and tile_column = ").append(x); statement.append(" and tile_row = ").append(Math.pow(2, zoomLevel) - y - 1); statement.append(" and map.tile_id = images.tile_id;"); ResultSet rs = stat.executeQuery(statement.toString()); while (rs.next()) { byte[] imageBytes = rs.getBytes("tile_data"); ImageIcon ii = new ImageIcon(imageBytes); BufferedImage bi = BufferedImageHelper.getBufferedImage(ii.getImage(), 0, 0, -1, -1); OMGraphic raster = createOMGraphicFromBufferedImage(bi, x, y, zoomLevel, proj); if (raster != null) { return new CacheObject((String) key, raster); } } rs.close(); conn.close(); } catch (Exception e) { logger.warning("something went wrong fetching image from database: " + e.getMessage()); e.printStackTrace(); } return null; } public Properties getProperties(Properties getList) { getList = super.getProperties(getList); if (testClass != null && !testClass.equals(DEFAULT_TEST_CLASS)) { getList.put(prefix + TEST_CLASS_PROPERTY, PropUtils.unnull(testClass)); } return getList; } public Properties getPropertyInfo(Properties list) { list = super.getPropertyInfo(list); I18n i18n = Environment.getI18n(); PropUtils.setI18NPropertyInfo(i18n, list, com.bbn.openmap.dataAccess.mapTile.StandardMapTileFactory.class, TEST_CLASS_PROPERTY, "JDBC Availability Test Class", "A class in the JDBC driver package to use to test for JDBC driver configuration (any class in package).", null); return list; } public void setProperties(String prefix, Properties setList) { super.setProperties(prefix, setList); prefix = PropUtils.getScopedPropertyPrefix(prefix); testClass = setList.getProperty(prefix + TEST_CLASS_PROPERTY, testClass); } }