diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 780a026003..bcfce2223a 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -16,8 +16,7 @@ public class ToDoConstants { // 80. Export/import favorite points // 81. Add some objects to POI to help navigation ( // highway (?), traffic_calming (?), barrier(?), military(?-), landuse (?), office(?), man_made(?), power(?). - // 79. Download any WMS layer and add to swing version (add tile manager ${x}, ${y}, ${z} to swing and to android) - + // BUGS : // 1. Show different aspect view for landscape mode (+) @@ -51,6 +50,7 @@ public class ToDoConstants { // DONE ANDROID : // 64. Traffic information - yandex traffic + // 79. Download any WMS layer and add to swing version (add tile manager ${x}, ${y}, ${z} to swing and to android) // DONE SWING diff --git a/DataExtractionOSM/src/com/osmand/map/TileSourceManager.java b/DataExtractionOSM/src/com/osmand/map/TileSourceManager.java index d947122347..dd0c3d5536 100644 --- a/DataExtractionOSM/src/com/osmand/map/TileSourceManager.java +++ b/DataExtractionOSM/src/com/osmand/map/TileSourceManager.java @@ -29,6 +29,11 @@ public class TileSourceManager { private int avgSize; private int bitDensity; + // default constructor + public TileSourceTemplate(String name, String urlToLoad){ + this(name, urlToLoad, ".jpg", 18, 1, 256, 16, 20000); //$NON-NLS-1$ + } + public TileSourceTemplate(String name, String urlToLoad, String ext, int maxZoom, int minZoom, int tileSize, int bitDensity, int avgSize) { this.maxZoom = maxZoom; this.minZoom = minZoom; @@ -76,12 +81,19 @@ public class TileSourceManager { @Override public String getUrlToLoad(int x, int y, int zoom) { // use int to string not format numbers! (non-nls) + if(urlToLoad == null){ + return null; + } return MessageFormat.format(urlToLoad, zoom+"", x+"", y+""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } + + public String getUrlTemplate(){ + return urlToLoad; + } @Override public boolean couldBeDownloadedFromInternet() { - return true; + return urlToLoad != null; } diff --git a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java index b1667fd458..9719158d95 100644 --- a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java +++ b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java @@ -590,7 +590,7 @@ public class OsmExtractionUI implements IMapLocationListener { @Override public void run() { try { - SQLiteBigPlanetIndex.createSQLiteDatabase(DataExtractionSettings.getSettings().getTilesDirectory(), regionName, map.getName()); + SQLiteBigPlanetIndex.createSQLiteDatabase(DataExtractionSettings.getSettings().getTilesDirectory(), regionName, map); } catch (SQLException e1) { throw new IllegalArgumentException(e1); } catch (IOException e1) { diff --git a/DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java b/DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java index 316bbe0eaa..b938eefa8b 100644 --- a/DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java +++ b/DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java @@ -12,13 +12,15 @@ import java.sql.Statement; import org.apache.commons.logging.Log; import com.osmand.LogUtil; +import com.osmand.map.ITileSource; +import com.osmand.map.TileSourceManager.TileSourceTemplate; public class SQLiteBigPlanetIndex { private static final Log log = LogUtil.getLog(SQLiteBigPlanetIndex.class); private static final int BATCH_SIZE = 50; - public static void createSQLiteDatabase(File dirWithTiles, String regionName, String tileSource) throws SQLException, IOException { + public static void createSQLiteDatabase(File dirWithTiles, String regionName, ITileSource template) throws SQLException, IOException { long now = System.currentTimeMillis(); try { Class.forName("org.sqlite.JDBC"); //$NON-NLS-1$ @@ -26,26 +28,36 @@ public class SQLiteBigPlanetIndex { log.error("Illegal configuration", e); //$NON-NLS-1$ throw new IllegalStateException(e); } - File fileToWrite = new File(dirWithTiles, regionName + "." + tileSource + ".sqlitedb"); + File fileToWrite = new File(dirWithTiles, regionName + "." + template.getName() + ".sqlitedb"); fileToWrite.delete(); Connection conn = DriverManager.getConnection("jdbc:sqlite:" + fileToWrite.getAbsolutePath()); //$NON-NLS-1$ Statement statement = conn.createStatement(); statement.execute("CREATE TABLE tiles (x int, y int, z int, s int, image blob, PRIMARY KEY (x,y,z,s))"); statement.execute("CREATE INDEX IND on tiles (x,y,z,s)"); - statement.execute("CREATE TABLE info(minzoom,maxzoom)"); + statement.execute("CREATE TABLE info(minzoom,maxzoom,url)"); statement.execute("CREATE TABLE android_metadata (locale TEXT)"); statement.close(); + + + PreparedStatement pStatement = conn.prepareStatement("INSERT INTO INFO VALUES(?,?,?)"); + if (template instanceof TileSourceTemplate) { + pStatement.setInt(1, template.getMinimumZoomSupported()); + pStatement.setInt(2, template.getMaximumZoomSupported()); + pStatement.setString(3, ((TileSourceTemplate) template).getUrlTemplate()); + pStatement.execute(); + } + pStatement.close(); + conn.setAutoCommit(false); - - PreparedStatement pStatement = conn.prepareStatement("INSERT INTO tiles VALUES (?, ?, ?, ?, ?)"); + pStatement = conn.prepareStatement("INSERT INTO tiles VALUES (?, ?, ?, ?, ?)"); int ch = 0; int bufSize = 32 * 1024; byte[] buf = new byte[bufSize]; int maxZoom = 17; int minZoom = 1; - File rootDir = new File(dirWithTiles, tileSource); + File rootDir = new File(dirWithTiles, template.getName()); for(File z : rootDir.listFiles()){ try { int zoom = Integer.parseInt(z.getName()); diff --git a/OsmAnd/src/com/osmand/OsmandSettings.java b/OsmAnd/src/com/osmand/OsmandSettings.java index 5e6ed78a8c..529c8d2057 100644 --- a/OsmAnd/src/com/osmand/OsmandSettings.java +++ b/OsmAnd/src/com/osmand/OsmandSettings.java @@ -1,7 +1,12 @@ package com.osmand; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; import java.util.List; +import java.util.regex.Pattern; import android.content.Context; import android.content.SharedPreferences; @@ -9,6 +14,7 @@ import android.content.SharedPreferences.Editor; import android.content.pm.ActivityInfo; import android.location.LocationManager; import android.os.Environment; +import android.util.Log; import com.osmand.activities.RouteProvider.RouteService; import com.osmand.activities.search.SearchHistoryHelper; @@ -304,16 +310,35 @@ public class OsmandSettings { SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); String tileName = prefs.getString(MAP_TILE_SOURCES, null); if (tileName != null) { - if(tileName.endsWith(SQLiteTileSource.EXT)){ - File file = new File(Environment.getExternalStorageDirectory(), ResourceManager.TILES_PATH); - return new SQLiteTileSource(new File(file, tileName)); - } + List list = TileSourceManager.getKnownSourceTemplates(); for (TileSourceTemplate l : list) { if (l.getName().equals(tileName)) { return l; } } + File tPath = new File(Environment.getExternalStorageDirectory(), ResourceManager.TILES_PATH); + File dir = new File(tPath, tileName); + if(dir.exists()){ + if(tileName.endsWith(SQLiteTileSource.EXT)){ + return new SQLiteTileSource(dir); + } else if (dir.isDirectory()) { + String url = null; + File readUrl = new File(dir, "url"); //$NON-NLS-1$ + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(readUrl), "UTF-8")); //$NON-NLS-1$ + url = reader.readLine(); + url = url.replaceAll(Pattern.quote("{$z}"), "{0}"); //$NON-NLS-1$ //$NON-NLS-2$ + url = url.replaceAll(Pattern.quote("{$x}"), "{1}"); //$NON-NLS-1$//$NON-NLS-2$ + url = url.replaceAll(Pattern.quote("{$y}"), "{2}"); //$NON-NLS-1$ //$NON-NLS-2$ + reader.close(); + } catch (IOException e) { + Log.d(LogUtil.TAG, "Error reading url " + dir.getName(), e); //$NON-NLS-1$ + } + return new TileSourceManager.TileSourceTemplate(dir.getName(), url); + } + } + } return TileSourceManager.getMapnikSource(); } diff --git a/OsmAnd/src/com/osmand/ResourceManager.java b/OsmAnd/src/com/osmand/ResourceManager.java index e4b624d96e..e9710de846 100644 --- a/OsmAnd/src/com/osmand/ResourceManager.java +++ b/OsmAnd/src/com/osmand/ResourceManager.java @@ -44,6 +44,7 @@ public class ResourceManager { public static final String ADDRESS_PATH = APP_DIR + IndexConstants.ADDRESS_INDEX_DIR; public static final String TRANSPORT_PATH = APP_DIR + IndexConstants.TRANSPORT_INDEX_DIR; public static final String TILES_PATH = APP_DIR+"tiles/"; //$NON-NLS-1$ + public static final String TEMP_SOURCE_TO_LOAD = "temp"; //$NON-NLS-1$ public static final int LIMIT_TRANSPORT = 200; @@ -139,6 +140,14 @@ public class ResourceManager { log.warn("File "+req.fileToSave.getName() + " couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$ } req.fileToSave.delete(); + String[] l = req.fileToSave.getParentFile().list(); + if(l == null || l.length == 0){ + req.fileToSave.getParentFile().delete(); + l = req.fileToSave.getParentFile().getParentFile().list(); + if(l == null || l.length == 0){ + req.fileToSave.getParentFile().getParentFile().delete(); + } + } } } @@ -180,14 +189,19 @@ public class ResourceManager { protected StringBuilder builder = new StringBuilder(40); public synchronized String calculateTileId(ITileSource map, int x, int y, int zoom){ builder.setLength(0); - builder.append(map.getName()); + if(map == null){ + builder.append(TEMP_SOURCE_TO_LOAD); + } else { + builder.append(map.getName()); + } + if(map instanceof SQLiteTileSource){ builder.append('@'); } else { builder.append('/'); } builder.append(zoom).append('/').append(x). - append('/').append(y).append(map.getTileFormat()).append(".tile"); //$NON-NLS-1$ + append('/').append(y).append(map == null ? ".jpg" : map.getTileFormat()).append(".tile"); //$NON-NLS-1$ //$NON-NLS-2$ String file = builder.toString(); return file; } @@ -223,8 +237,7 @@ public class ResourceManager { File toSave = null; if (url != null) { if (map instanceof SQLiteTileSource) { - ITileSource base = ((SQLiteTileSource) map).getBase(); - toSave = new File(dirWithTiles, calculateTileId(base, x, y, zoom)); + toSave = new File(dirWithTiles, calculateTileId(((SQLiteTileSource) map).getBase(), x, y, zoom)); } else { toSave = new File(dirWithTiles, tileId); } diff --git a/OsmAnd/src/com/osmand/SQLiteTileSource.java b/OsmAnd/src/com/osmand/SQLiteTileSource.java index 15c2ef5937..7e1481f879 100644 --- a/OsmAnd/src/com/osmand/SQLiteTileSource.java +++ b/OsmAnd/src/com/osmand/SQLiteTileSource.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.text.MessageFormat; import org.apache.commons.logging.Log; @@ -15,6 +16,7 @@ import android.graphics.BitmapFactory; import com.osmand.map.ITileSource; import com.osmand.map.TileSourceManager; +import com.osmand.map.TileSourceManager.TileSourceTemplate; public class SQLiteTileSource implements ITileSource { @@ -23,6 +25,7 @@ public class SQLiteTileSource implements ITileSource { private static final Log log = LogUtil.getLog(SQLiteTileSource.class); private ITileSource base; + private String urlTemplate = null; private String name; private SQLiteDatabase db; private final File file; @@ -34,9 +37,10 @@ public class SQLiteTileSource implements ITileSource { i = name.lastIndexOf('.'); if(i > 0){ String sourceName = name.substring(i+1); - for(ITileSource is : TileSourceManager.getKnownSourceTemplates()){ + for(TileSourceTemplate is : TileSourceManager.getKnownSourceTemplates()){ if(is.getName().equalsIgnoreCase(sourceName)){ base = is; + urlTemplate = is.getUrlTemplate(); break; } } @@ -77,10 +81,10 @@ public class SQLiteTileSource implements ITileSource { @Override public String getUrlToLoad(int x, int y, int zoom) { SQLiteDatabase db = getDatabase(); - if(db == null || db.isReadOnly()){ + if(db == null || db.isReadOnly() || urlTemplate == null){ return null; } - return base != null ? base.getUrlToLoad(x, y, zoom) : null; + return MessageFormat.format(urlTemplate, zoom+"", x+"", y+""); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } @Override @@ -117,6 +121,13 @@ public class SQLiteTileSource implements ITileSource { private SQLiteDatabase getDatabase(){ if(db == null && file.exists()){ db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, 0); + try { + String template = db.compileStatement("SELECT url FROM info").simpleQueryForString(); //$NON-NLS-1$ + if(!Algoritms.isEmpty(template)){ + urlTemplate = template; + } + } catch (RuntimeException e) { + } } return db; } @@ -203,10 +214,10 @@ public class SQLiteTileSource implements ITileSource { @Override public boolean couldBeDownloadedFromInternet() { - if(getDatabase() == null || getDatabase().isReadOnly() || base == null){ + if(getDatabase() == null || getDatabase().isReadOnly()){ return false; } - return base.couldBeDownloadedFromInternet(); + return urlTemplate != null; } diff --git a/OsmAnd/src/com/osmand/activities/SettingsActivity.java b/OsmAnd/src/com/osmand/activities/SettingsActivity.java index b32acfc265..c04cdc949e 100644 --- a/OsmAnd/src/com/osmand/activities/SettingsActivity.java +++ b/OsmAnd/src/com/osmand/activities/SettingsActivity.java @@ -335,6 +335,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference if (f.getName().endsWith(SQLiteTileSource.EXT)) { String n = f.getName(); map.put(f.getName(), n.substring(0, n.indexOf('.'))); + } else if(f.isDirectory() && !f.getName().equals(ResourceManager.TEMP_SOURCE_TO_LOAD)){ + map.put(f.getName(), f.getName()); } } }