implement sqlite db
git-svn-id: https://osmand.googlecode.com/svn/trunk@366 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
3f8e13c79c
commit
3c85f1418e
12 changed files with 549 additions and 78 deletions
|
@ -11,6 +11,7 @@ public class ToDoConstants {
|
||||||
// TODO ANDROID
|
// TODO ANDROID
|
||||||
// for 0.3
|
// for 0.3
|
||||||
// 71. Implement different mechanism for tiles (big sqlite planet see rmaps)
|
// 71. Implement different mechanism for tiles (big sqlite planet see rmaps)
|
||||||
|
// 1) doc, 2) test (update map, download from internet...), 3) add button menu create sqlite db
|
||||||
|
|
||||||
// Improvement : Show stops in the transport route on the map
|
// Improvement : Show stops in the transport route on the map
|
||||||
// Improvement : show favorites on the map?
|
// Improvement : show favorites on the map?
|
||||||
|
@ -19,7 +20,6 @@ public class ToDoConstants {
|
||||||
// Improvement : redesign poi selecting (show on map )
|
// Improvement : redesign poi selecting (show on map )
|
||||||
// Improvement : progress while loading tiles
|
// Improvement : progress while loading tiles
|
||||||
// Improvement : download with wget
|
// Improvement : download with wget
|
||||||
// Improvement : cloudmade as map?
|
|
||||||
// Yandex traffic : http://jgo.maps.yandex.net/tiles?l=trf
|
// Yandex traffic : http://jgo.maps.yandex.net/tiles?l=trf
|
||||||
// Improvement : show route info after route is calculated and/or calculate route from context menu
|
// Improvement : show route info after route is calculated and/or calculate route from context menu
|
||||||
// (continue follow previous route)
|
// (continue follow previous route)
|
||||||
|
|
|
@ -15,4 +15,8 @@ public interface ITileSource {
|
||||||
|
|
||||||
public String getTileFormat();
|
public String getTileFormat();
|
||||||
|
|
||||||
|
public int getBitDensity();
|
||||||
|
|
||||||
|
public boolean couldBeDownloadedFromInternet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,9 @@ public class TileSourceManager {
|
||||||
private String urlToLoad;
|
private String urlToLoad;
|
||||||
private String ext;
|
private String ext;
|
||||||
private int avgSize;
|
private int avgSize;
|
||||||
|
private int bitDensity;
|
||||||
|
|
||||||
public TileSourceTemplate(String name, String urlToLoad, String ext, int maxZoom, int minZoom, int tileSize, int avgSize) {
|
public TileSourceTemplate(String name, String urlToLoad, String ext, int maxZoom, int minZoom, int tileSize, int bitDensity, int avgSize) {
|
||||||
this.maxZoom = maxZoom;
|
this.maxZoom = maxZoom;
|
||||||
this.minZoom = minZoom;
|
this.minZoom = minZoom;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -25,8 +26,13 @@ public class TileSourceManager {
|
||||||
this.urlToLoad = urlToLoad;
|
this.urlToLoad = urlToLoad;
|
||||||
this.ext = ext;
|
this.ext = ext;
|
||||||
this.avgSize = avgSize;
|
this.avgSize = avgSize;
|
||||||
|
this.bitDensity = bitDensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBitDensity() {
|
||||||
|
return bitDensity;
|
||||||
|
}
|
||||||
|
|
||||||
public int getAverageSize(){
|
public int getAverageSize(){
|
||||||
return avgSize;
|
return avgSize;
|
||||||
|
@ -61,6 +67,11 @@ public class TileSourceManager {
|
||||||
// use int to string not format numbers! (non-nls)
|
// use int to string not format numbers! (non-nls)
|
||||||
return MessageFormat.format(urlToLoad, zoom+"", x+"", y+""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return MessageFormat.format(urlToLoad, zoom+"", x+"", y+""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean couldBeDownloadedFromInternet() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -123,60 +134,60 @@ public class TileSourceManager {
|
||||||
|
|
||||||
|
|
||||||
public static TileSourceTemplate getMapnikSource(){
|
public static TileSourceTemplate getMapnikSource(){
|
||||||
return new TileSourceTemplate("Mapnik", "http://tile.openstreetmap.org/{0}/{1}/{2}.png", ".png", 18, 1, 256, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("Mapnik", "http://tile.openstreetmap.org/{0}/{1}/{2}.png", ".png", 18, 1, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getOsmaRenderSource(){
|
public static TileSourceTemplate getOsmaRenderSource(){
|
||||||
return new TileSourceTemplate("OsmaRender", "http://tah.openstreetmap.org/Tiles/tile/{0}/{1}/{2}.png", ".png", 17, 1, 256, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("OsmaRender", "http://tah.openstreetmap.org/Tiles/tile/{0}/{1}/{2}.png", ".png", 17, 1, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getCycleMapSource(){
|
public static TileSourceTemplate getCycleMapSource(){
|
||||||
return new TileSourceTemplate("CycleMap", "http://b.andy.sandbox.cloudmade.com/tiles/cycle/{0}/{1}/{2}.png", ".png", 17, 0, 256, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("CycleMap", "http://b.andy.sandbox.cloudmade.com/tiles/cycle/{0}/{1}/{2}.png", ".png", 17, 0, 256, 32, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getAerialMapSource(){
|
public static TileSourceTemplate getAerialMapSource(){
|
||||||
return new TileSourceTemplate("OpenAerialMap", "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/{0}/{1}/{2}.jpg", ".jpg", 13, 0, 256, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("OpenAerialMap", "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/{0}/{1}/{2}.jpg", ".jpg", 13, 0, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getCloudMadeSource(){
|
public static TileSourceTemplate getCloudMadeSource(){
|
||||||
return new TileSourceTemplate("Cloudmade", "http://tile.cloudmade.com/7ded028e030c5929b28bf823486ce84f/1/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("Cloudmade", "http://tile.cloudmade.com/7ded028e030c5929b28bf823486ce84f/1/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 16, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getMapSurferSource(){
|
public static TileSourceTemplate getMapSurferSource(){
|
||||||
return new TileSourceTemplate("MapSurfer", "http://tiles1.mapsurfer.net/tms_r.ashx?z={0}&x={1}&y={2}", ".png", 19, 0, 256, 18000);//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("MapSurfer", "http://tiles1.mapsurfer.net/tms_r.ashx?z={0}&x={1}&y={2}", ".png", 19, 0, 256, 16, 18000);//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getNavigationDebugSource(){
|
public static TileSourceTemplate getNavigationDebugSource(){
|
||||||
return new TileSourceTemplate("NavigationDebug", "http://ec2-184-73-15-218.compute-1.amazonaws.com/6700/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("NavigationDebug", "http://ec2-184-73-15-218.compute-1.amazonaws.com/6700/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static TileSourceTemplate getOpenPisteMapSource(){
|
public static TileSourceTemplate getOpenPisteMapSource(){
|
||||||
return new TileSourceTemplate("OpenPisteMap", "http://openpistemap.org/tiles/contours/{0}/{1}/{2}.png", ".png", 17, 0, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("OpenPisteMap", "http://openpistemap.org/tiles/contours/{0}/{1}/{2}.png", ".png", 17, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getGoogleMapsSource(){
|
public static TileSourceTemplate getGoogleMapsSource(){
|
||||||
return new TileSourceTemplate("GoogleMaps", "http://mt3.google.com/vt/v=w2.97&x={1}&y={2}&z={0}", ".png", 19, 0, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("GoogleMaps", "http://mt3.google.com/vt/v=w2.97&x={1}&y={2}&z={0}", ".png", 19, 0, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getGoogleMapsSatelliteSource(){
|
public static TileSourceTemplate getGoogleMapsSatelliteSource(){
|
||||||
return new TileSourceTemplate("GoogleMaps Satellite", "http://khm1.google.com/kh/v=59&x={1}&y={2}&z={0}", ".jpg", 20, 0, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("GoogleMaps Satellite", "http://khm1.google.com/kh/v=59&x={1}&y={2}&z={0}", ".jpg", 20, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getGoogleMapsTerrainSource(){
|
public static TileSourceTemplate getGoogleMapsTerrainSource(){
|
||||||
return new TileSourceTemplate("GoogleMaps Terrain", "http://mt3.google.com/vt/v=w2p.111&hl=en&x={1}&y={2}&z={0}", ".jpg", 15, 0, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new TileSourceTemplate("GoogleMaps Terrain", "http://mt3.google.com/vt/v=w2p.111&hl=en&x={1}&y={2}&z={0}", ".jpg", 15, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getMicrosoftMapsSource(){
|
public static TileSourceTemplate getMicrosoftMapsSource(){
|
||||||
return new MicrosoftTileSourceTemplate("Microsoft Maps", 'r', "png", ".png", 19, 1, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new MicrosoftTileSourceTemplate("Microsoft Maps", 'r', "png", ".png", 19, 1, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getMicrosoftEarthSource(){
|
public static TileSourceTemplate getMicrosoftEarthSource(){
|
||||||
return new MicrosoftTileSourceTemplate("Microsoft Earth", 'a', "jpg", ".jpg", 19, 1, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new MicrosoftTileSourceTemplate("Microsoft Earth", 'a', "jpg", ".jpg", 19, 1, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TileSourceTemplate getMicrosoftHybridSource(){
|
public static TileSourceTemplate getMicrosoftHybridSource(){
|
||||||
return new MicrosoftTileSourceTemplate("Microsoft Hybrid", 'h', "jpg", ".jpg", 19, 1, 256, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
return new MicrosoftTileSourceTemplate("Microsoft Hybrid", 'h', "jpg", ".jpg", 19, 1, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,8 +223,8 @@ public class TileSourceManager {
|
||||||
private final String tileType;
|
private final String tileType;
|
||||||
|
|
||||||
public MicrosoftTileSourceTemplate(String name, char mapTypeChar , String type,
|
public MicrosoftTileSourceTemplate(String name, char mapTypeChar , String type,
|
||||||
String ext, int maxZoom, int minZoom, int tileSize, int avgSize) {
|
String ext, int maxZoom, int minZoom, int tileSize, int bitDensity, int avgSize) {
|
||||||
super(name, null, ext, maxZoom, minZoom, tileSize, avgSize);
|
super(name, null, ext, maxZoom, minZoom, tileSize, bitDensity, avgSize);
|
||||||
this.mapTypeChar = mapTypeChar;
|
this.mapTypeChar = mapTypeChar;
|
||||||
this.tileType = type;
|
this.tileType = type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
||||||
menuItem.addActionListener(new ActionListener(){
|
menuItem.addActionListener(new ActionListener(){
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
for(int i=0; i<tiles.getItemCount(); i++){
|
for(int i=0; i<list.size() ; i++){
|
||||||
if(list.get(i).equals(l)){
|
if(list.get(i).equals(l)){
|
||||||
((JCheckBoxMenuItem)tiles.getItem(i)).setSelected(true);
|
((JCheckBoxMenuItem)tiles.getItem(i)).setSelected(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -78,6 +78,7 @@ import com.osmand.data.City.CityType;
|
||||||
import com.osmand.data.index.DataIndexWriter;
|
import com.osmand.data.index.DataIndexWriter;
|
||||||
import com.osmand.data.preparation.DataExtraction;
|
import com.osmand.data.preparation.DataExtraction;
|
||||||
import com.osmand.map.IMapLocationListener;
|
import com.osmand.map.IMapLocationListener;
|
||||||
|
import com.osmand.map.ITileSource;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
|
@ -541,7 +542,11 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
JMenuItem exitMenu= new JMenuItem("Exit");
|
JMenuItem exitMenu= new JMenuItem("Exit");
|
||||||
menu.add(exitMenu);
|
menu.add(exitMenu);
|
||||||
|
|
||||||
bar.add(MapPanel.getMenuToChooseSource(mapPanel));
|
JMenu tileSource = MapPanel.getMenuToChooseSource(mapPanel);
|
||||||
|
tileSource.addSeparator();
|
||||||
|
JMenuItem sqliteDB = new JMenuItem("Create sqlite database");
|
||||||
|
tileSource.add(sqliteDB);
|
||||||
|
bar.add(tileSource);
|
||||||
|
|
||||||
menu = new JMenu("Window");
|
menu = new JMenu("Window");
|
||||||
bar.add(menu);
|
bar.add(menu);
|
||||||
|
@ -572,6 +577,39 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sqliteDB.addActionListener(new ActionListener(){
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
final String regionName = region == null ? "Region" : region.getName();
|
||||||
|
final ITileSource map = mapPanel.getMap();
|
||||||
|
if(map != null){
|
||||||
|
try {
|
||||||
|
final ProgressDialog dlg = new ProgressDialog(frame, "Creating index");
|
||||||
|
dlg.setRunnable(new Runnable(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
SQLiteBigPlanetIndex.createSQLiteDatabase(DataExtractionSettings.getSettings().getTilesDirectory(), regionName, map.getName());
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
throw new IllegalArgumentException(e1);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
throw new IllegalArgumentException(e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.run();
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
log.error("Interrupted", e1);
|
||||||
|
} catch (InvocationTargetException e1) {
|
||||||
|
ExceptionHandler.handle("Can't create big planet sqlite index", (Exception) e1.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
exitMenu.addActionListener(new ActionListener(){
|
exitMenu.addActionListener(new ActionListener(){
|
||||||
|
|
109
DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java
Normal file
109
DataExtractionOSM/src/com/osmand/swing/SQLiteBigPlanetIndex.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package com.osmand.swing;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import com.osmand.LogUtil;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC"); //$NON-NLS-1$
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.error("Illegal configuration", e); //$NON-NLS-1$
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
File fileToWrite = new File(dirWithTiles, regionName + "." + tileSource + ".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 android_metadata (locale TEXT)");
|
||||||
|
statement.close();
|
||||||
|
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
PreparedStatement 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);
|
||||||
|
for(File z : rootDir.listFiles()){
|
||||||
|
try {
|
||||||
|
int zoom = Integer.parseInt(z.getName());
|
||||||
|
for(File xDir : z.listFiles()){
|
||||||
|
try {
|
||||||
|
int x = Integer.parseInt(xDir.getName());
|
||||||
|
for(File f : xDir.listFiles()){
|
||||||
|
if(!f.isFile()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int i = f.getName().indexOf('.');
|
||||||
|
int y = Integer.parseInt(f.getName().substring(0, i));
|
||||||
|
buf = new byte[(int) f.length()];
|
||||||
|
if(zoom > maxZoom){
|
||||||
|
maxZoom = zoom;
|
||||||
|
}
|
||||||
|
if(zoom < minZoom){
|
||||||
|
minZoom = zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInputStream is = new FileInputStream(f);
|
||||||
|
int l = is.read(buf);
|
||||||
|
if (l > 0) {
|
||||||
|
pStatement.setInt(1, x);
|
||||||
|
pStatement.setInt(2, y);
|
||||||
|
pStatement.setInt(3, zoom);
|
||||||
|
pStatement.setInt(4, 0);
|
||||||
|
pStatement.setBytes(5, buf);
|
||||||
|
pStatement.addBatch();
|
||||||
|
ch++;
|
||||||
|
if (ch >= BATCH_SIZE) {
|
||||||
|
pStatement.executeBatch();
|
||||||
|
ch = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch > 0) {
|
||||||
|
pStatement.executeBatch();
|
||||||
|
ch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStatement.close();
|
||||||
|
conn.commit();
|
||||||
|
conn.close();
|
||||||
|
log.info("Index created " + fileToWrite.getName() + " " + (System.currentTimeMillis() - now) + " ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package com.osmand;
|
package com.osmand;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -7,6 +8,7 @@ import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
import com.osmand.activities.RouteProvider.RouteService;
|
import com.osmand.activities.RouteProvider.RouteService;
|
||||||
import com.osmand.activities.search.SearchHistoryHelper;
|
import com.osmand.activities.search.SearchHistoryHelper;
|
||||||
|
@ -278,6 +280,10 @@ public class OsmandSettings {
|
||||||
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||||
String tileName = prefs.getString(MAP_TILE_SOURCES, null);
|
String tileName = prefs.getString(MAP_TILE_SOURCES, null);
|
||||||
if (tileName != 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<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
||||||
for (TileSourceTemplate l : list) {
|
for (TileSourceTemplate l : list) {
|
||||||
if (l.getName().equals(tileName)) {
|
if (l.getName().equals(tileName)) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.osmand;
|
package com.osmand;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -58,7 +59,7 @@ public class ResourceManager {
|
||||||
|
|
||||||
// it is not good investigated but no more than 64 (satellite images)
|
// it is not good investigated but no more than 64 (satellite images)
|
||||||
// Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit
|
// Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit
|
||||||
protected final int maxImgCacheSize = 48;
|
protected int maxImgCacheSize = 48;
|
||||||
|
|
||||||
protected Map<String, Bitmap> cacheOfImages = new LinkedHashMap<String, Bitmap>();
|
protected Map<String, Bitmap> cacheOfImages = new LinkedHashMap<String, Bitmap>();
|
||||||
protected Map<String, Boolean> imagesOnFS = new LinkedHashMap<String, Boolean>() ;
|
protected Map<String, Boolean> imagesOnFS = new LinkedHashMap<String, Boolean>() ;
|
||||||
|
@ -107,7 +108,7 @@ public class ResourceManager {
|
||||||
} else if(f.getName().endsWith(".tile")){ //$NON-NLS-1$
|
} else if(f.getName().endsWith(".tile")){ //$NON-NLS-1$
|
||||||
imagesOnFS.put(prefix + f.getName(), Boolean.TRUE);
|
imagesOnFS.put(prefix + f.getName(), Boolean.TRUE);
|
||||||
} else if(f.getName().endsWith(".sqlitedb")){ //$NON-NLS-1$
|
} else if(f.getName().endsWith(".sqlitedb")){ //$NON-NLS-1$
|
||||||
// TODO
|
// nothing to do here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,13 +127,34 @@ public class ResourceManager {
|
||||||
return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, true, true);
|
return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void tileDownloaded(String file){
|
public synchronized void tileDownloaded(DownloadRequest request){
|
||||||
imagesOnFS.put(file, Boolean.TRUE);
|
if(request instanceof TileLoadDownloadRequest){
|
||||||
|
TileLoadDownloadRequest req = ((TileLoadDownloadRequest) request);
|
||||||
|
imagesOnFS.put(req.tileId, Boolean.TRUE);
|
||||||
|
if(req.fileToSave != null && req.tileSource instanceof SQLiteTileSource){
|
||||||
|
try {
|
||||||
|
((SQLiteTileSource) req.tileSource).insertImage(req.xTile, req.yTile, req.zoom, req.fileToSave);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("File "+req.fileToSave.getName() + " couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
}
|
||||||
|
req.fileToSave.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean tileExistOnFileSystem(String file){
|
public synchronized boolean tileExistOnFileSystem(String file, ITileSource map, int x, int y, int zoom){
|
||||||
if(!imagesOnFS.containsKey(file)){
|
if(!imagesOnFS.containsKey(file)){
|
||||||
if(new File(dirWithTiles, file).exists()){
|
boolean ex = false;
|
||||||
|
if(map instanceof SQLiteTileSource){
|
||||||
|
ex = ((SQLiteTileSource) map).exists(x, y, zoom);
|
||||||
|
} else {
|
||||||
|
if(file == null){
|
||||||
|
file = calculateTileId(map, x, y, zoom);
|
||||||
|
}
|
||||||
|
ex = new File(dirWithTiles, file).exists();
|
||||||
|
}
|
||||||
|
if (ex) {
|
||||||
imagesOnFS.put(file, Boolean.TRUE);
|
imagesOnFS.put(file, Boolean.TRUE);
|
||||||
} else {
|
} else {
|
||||||
imagesOnFS.put(file, null);
|
imagesOnFS.put(file, null);
|
||||||
|
@ -157,78 +179,106 @@ public class ResourceManager {
|
||||||
protected StringBuilder builder = new StringBuilder(40);
|
protected StringBuilder builder = new StringBuilder(40);
|
||||||
public synchronized String calculateTileId(ITileSource map, int x, int y, int zoom){
|
public synchronized String calculateTileId(ITileSource map, int x, int y, int zoom){
|
||||||
builder.setLength(0);
|
builder.setLength(0);
|
||||||
builder.append(map.getName()).append('/').append(zoom). append('/').append(x).
|
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.getTileFormat()).append(".tile"); //$NON-NLS-1$
|
||||||
String file = builder.toString();
|
String file = builder.toString();
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected synchronized Bitmap getTileImageForMap(String file, ITileSource map, int x, int y, int zoom,
|
protected synchronized Bitmap getTileImageForMap(String tileId, ITileSource map, int x, int y, int zoom,
|
||||||
boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs, boolean deleteBefore) {
|
boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs, boolean deleteBefore) {
|
||||||
if (file == null) {
|
if (tileId == null) {
|
||||||
file = calculateTileId(map, x, y, zoom);
|
tileId = calculateTileId(map, x, y, zoom);
|
||||||
if(file == null){
|
if(tileId == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deleteBefore){
|
if(deleteBefore){
|
||||||
cacheOfImages.remove(file);
|
cacheOfImages.remove(tileId);
|
||||||
File f = new File(dirWithTiles, file);
|
if (map instanceof SQLiteTileSource) {
|
||||||
if(f.exists()){
|
((SQLiteTileSource) map).deleteImage(x, y, zoom);
|
||||||
f.delete();
|
} else {
|
||||||
imagesOnFS.put(file, null);
|
File f = new File(dirWithTiles, tileId);
|
||||||
|
if (f.exists()) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
imagesOnFS.put(tileId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadFromFs && cacheOfImages.get(file) == null) {
|
if (loadFromFs && cacheOfImages.get(tileId) == null) {
|
||||||
if(!loadFromInternetIfNeeded && !tileExistOnFileSystem(file)){
|
if(!loadFromInternetIfNeeded && !tileExistOnFileSystem(tileId, map, x, y, zoom)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String url = loadFromInternetIfNeeded ? map.getUrlToLoad(x, y, zoom) : null;
|
String url = loadFromInternetIfNeeded ? map.getUrlToLoad(x, y, zoom) : null;
|
||||||
TileLoadDownloadRequest req = new TileLoadDownloadRequest(dirWithTiles, file, url, new File(dirWithTiles, file),
|
File toSave = null;
|
||||||
x, y, zoom);
|
if (url != null) {
|
||||||
|
if (map instanceof SQLiteTileSource) {
|
||||||
|
ITileSource base = ((SQLiteTileSource) map).getBase();
|
||||||
|
toSave = new File(dirWithTiles, calculateTileId(base, x, y, zoom));
|
||||||
|
} else {
|
||||||
|
toSave = new File(dirWithTiles, tileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TileLoadDownloadRequest req = new TileLoadDownloadRequest(dirWithTiles, url, toSave,
|
||||||
|
tileId, map, x, y, zoom);
|
||||||
if(sync){
|
if(sync){
|
||||||
return getRequestedImageTile(req);
|
return getRequestedImageTile(req);
|
||||||
} else {
|
} else {
|
||||||
asyncLoadingTiles.requestToLoadImage(req);
|
asyncLoadingTiles.requestToLoadImage(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cacheOfImages.get(file);
|
return cacheOfImages.get(tileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Bitmap getRequestedImageTile(TileLoadDownloadRequest req){
|
private Bitmap getRequestedImageTile(TileLoadDownloadRequest req){
|
||||||
if(req.fileToLoad == null || req.dirWithTiles == null){
|
if(req.tileId == null || req.dirWithTiles == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
File en = new File(req.dirWithTiles, req.fileToLoad);
|
|
||||||
if (cacheOfImages.size() > maxImgCacheSize) {
|
if (cacheOfImages.size() > maxImgCacheSize) {
|
||||||
clearTiles();
|
clearTiles();
|
||||||
}
|
}
|
||||||
|
if (req.dirWithTiles.canRead() && !downloader.isFileCurrentlyDownloaded(req.fileToSave)) {
|
||||||
if (!downloader.isFileCurrentlyDownloaded(en) && req.dirWithTiles.canRead()) {
|
long time = System.currentTimeMillis();
|
||||||
if (en.exists()) {
|
Bitmap bmp = null;
|
||||||
long time = System.currentTimeMillis();
|
if (req.tileSource instanceof SQLiteTileSource) {
|
||||||
cacheOfImages.put(req.fileToLoad, BitmapFactory.decodeFile(en.getAbsolutePath()));
|
bmp = ((SQLiteTileSource) req.tileSource).getImage(req.xTile, req.yTile, req.zoom);
|
||||||
if (log.isDebugEnabled()) {
|
} else {
|
||||||
log.debug("Loaded file : " + req.fileToLoad + " " + -(time - System.currentTimeMillis()) + " ms " + cacheOfImages.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
File en = new File(req.dirWithTiles, req.tileId);
|
||||||
|
if (en.exists()) {
|
||||||
|
bmp = BitmapFactory.decodeFile(en.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cacheOfImages.get(req.fileToLoad) == null && req.url != null){
|
if (bmp != null) {
|
||||||
|
cacheOfImages.put(req.tileId, bmp);
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Loaded file : " + req.tileId + " " + -(time - System.currentTimeMillis()) + " ms " + cacheOfImages.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheOfImages.get(req.tileId) == null && req.url != null) {
|
||||||
// TODO we could check that network is available (context is required)
|
// TODO we could check that network is available (context is required)
|
||||||
// ConnectivityManager mgr = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
// ConnectivityManager mgr = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
// NetworkInfo info = mgr.getActiveNetworkInfo();
|
// NetworkInfo info = mgr.getActiveNetworkInfo();
|
||||||
// if (info != null && info.isConnected()) {
|
// if (info != null && info.isConnected()) {
|
||||||
// downloader.requestToDownload(req);
|
// downloader.requestToDownload(req);
|
||||||
// }
|
// }
|
||||||
downloader.requestToDownload(req);
|
downloader.requestToDownload(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return cacheOfImages.get(req.fileToLoad);
|
return cacheOfImages.get(req.tileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////// Working with indexes ////////////////////////////////////////////////
|
////////////////////////////////////////////// Working with indexes ////////////////////////////////////////////////
|
||||||
|
@ -444,6 +494,25 @@ public class ResourceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized void setMapSource(ITileSource source){
|
||||||
|
log.info("Clear cache with new source " + cacheOfImages.size()); //$NON-NLS-1$
|
||||||
|
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
||||||
|
// remove first images (as we think they are older)
|
||||||
|
for (int i = 0; i < list.size(); i ++) {
|
||||||
|
Bitmap bmp = cacheOfImages.remove(list.get(i));
|
||||||
|
if(bmp != null){
|
||||||
|
bmp.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(source == null || source.getBitDensity() == 0){
|
||||||
|
maxImgCacheSize = 48;
|
||||||
|
} else {
|
||||||
|
maxImgCacheSize = 1024 / source.getBitDensity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected synchronized void clearTiles(){
|
protected synchronized void clearTiles(){
|
||||||
log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$
|
log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$
|
||||||
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
||||||
|
@ -462,14 +531,16 @@ public class ResourceManager {
|
||||||
|
|
||||||
private static class TileLoadDownloadRequest extends DownloadRequest {
|
private static class TileLoadDownloadRequest extends DownloadRequest {
|
||||||
|
|
||||||
public final String fileToLoad;
|
public final String tileId;
|
||||||
public final File dirWithTiles;
|
public final File dirWithTiles;
|
||||||
|
public final ITileSource tileSource;
|
||||||
|
|
||||||
public TileLoadDownloadRequest(File dirWithTiles,
|
public TileLoadDownloadRequest(File dirWithTiles, String url, File fileToSave,
|
||||||
String fileToLoad, String url, File fileToSave, int tileX, int tileY, int zoom) {
|
String tileId, ITileSource source, int tileX, int tileY, int zoom) {
|
||||||
super(url, fileToSave, tileX, tileY, zoom);
|
super(url, fileToSave, tileX, tileY, zoom);
|
||||||
this.dirWithTiles = dirWithTiles;
|
this.dirWithTiles = dirWithTiles;
|
||||||
this.fileToLoad = fileToLoad;
|
tileSource = source;
|
||||||
|
this.tileId = tileId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +604,7 @@ public class ResourceManager {
|
||||||
Object req = requests.pop();
|
Object req = requests.pop();
|
||||||
if (req instanceof TileLoadDownloadRequest) {
|
if (req instanceof TileLoadDownloadRequest) {
|
||||||
TileLoadDownloadRequest r = (TileLoadDownloadRequest) req;
|
TileLoadDownloadRequest r = (TileLoadDownloadRequest) req;
|
||||||
if (cacheOfImages.get(r.fileToLoad) == null) {
|
if (cacheOfImages.get(r.tileId) == null) {
|
||||||
update |= getRequestedImageTile(r) != null;
|
update |= getRequestedImageTile(r) != null;
|
||||||
}
|
}
|
||||||
} else if(req instanceof AmenityLoadRequest){
|
} else if(req instanceof AmenityLoadRequest){
|
||||||
|
|
194
OsmAnd/src/com/osmand/SQLiteTileSource.java
Normal file
194
OsmAnd/src/com/osmand/SQLiteTileSource.java
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
package com.osmand;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteStatement;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
|
||||||
|
import com.osmand.map.ITileSource;
|
||||||
|
import com.osmand.map.TileSourceManager;
|
||||||
|
|
||||||
|
public class SQLiteTileSource implements ITileSource {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String EXT = ".sqlitedb"; //$NON-NLS-1$
|
||||||
|
private ITileSource base;
|
||||||
|
private String name;
|
||||||
|
private SQLiteDatabase db;
|
||||||
|
private final File file;
|
||||||
|
|
||||||
|
public SQLiteTileSource(File f){
|
||||||
|
this.file = f;
|
||||||
|
int i = f.getName().lastIndexOf('.');
|
||||||
|
name = f.getName().substring(0, i);
|
||||||
|
i = name.lastIndexOf('.');
|
||||||
|
if(i > 0){
|
||||||
|
String sourceName = name.substring(i+1);
|
||||||
|
for(ITileSource is : TileSourceManager.getKnownSourceTemplates()){
|
||||||
|
if(is.getName().equalsIgnoreCase(sourceName)){
|
||||||
|
base = is;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBitDensity() {
|
||||||
|
return base != null ? base.getBitDensity() : 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaximumZoomSupported() {
|
||||||
|
return base != null ? base.getMaximumZoomSupported() : 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumZoomSupported() {
|
||||||
|
return base != null ? base.getMinimumZoomSupported() : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTileFormat() {
|
||||||
|
return base != null ? base.getTileFormat() : ".png"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTileSize() {
|
||||||
|
return base != null ? base.getTileSize() : 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrlToLoad(int x, int y, int zoom) {
|
||||||
|
if(getDatabase().isReadOnly()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return base != null ? base.getUrlToLoad(x, y, zoom) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((base == null) ? 0 : base.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
SQLiteTileSource other = (SQLiteTileSource) obj;
|
||||||
|
if (base == null) {
|
||||||
|
if (other.base != null)
|
||||||
|
return false;
|
||||||
|
} else if (!base.equals(other.base))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SQLiteDatabase getDatabase(){
|
||||||
|
if(db == null){
|
||||||
|
db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, 0);
|
||||||
|
}
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean exists(int x, int y, int zoom) {
|
||||||
|
Cursor cursor = getDatabase().rawQuery("SELECT 1 FROM tiles WHERE x = ? AND y = ? AND z = ?", new String[] {x+"", y+"",(17 - zoom)+""}); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||||
|
boolean e = cursor.moveToFirst();
|
||||||
|
cursor.close();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap getImage(int x, int y, int zoom) {
|
||||||
|
Cursor cursor = getDatabase().rawQuery("SELECT image FROM tiles WHERE x = ? AND y = ? AND z = ?", new String[] {x+"", y+"",(17 - zoom)+""}); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||||
|
byte[] blob = null;
|
||||||
|
if(cursor.moveToFirst()) {
|
||||||
|
blob = cursor.getBlob(0);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
if(blob != null){
|
||||||
|
return BitmapFactory.decodeByteArray(blob, 0, blob.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITileSource getBase() {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteImage(int x, int y, int zoom) {
|
||||||
|
if(getDatabase().isReadOnly()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getDatabase().execSQL("DELETE FROM tiles WHERE x = ? AND y = ? AND z = ?", new String[] {x+"", y+"",(17 - zoom)+""}); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int BUF_SIZE = 1024;
|
||||||
|
|
||||||
|
public void insertImage(int x, int y, int zoom, File fileToSave) throws IOException {
|
||||||
|
if(exists(x, y, zoom)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate((int) fileToSave.length());
|
||||||
|
FileInputStream is = new FileInputStream(fileToSave);
|
||||||
|
int i = 0;
|
||||||
|
byte[] b = new byte[BUF_SIZE];
|
||||||
|
while((i=is.read(b, 0, BUF_SIZE)) > - 1){
|
||||||
|
buf.put(b, 0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLiteStatement statement = getDatabase().compileStatement("INSERT INTO tiles VALUES(?, ?, ?, ?, ?)"); //$NON-NLS-1$
|
||||||
|
statement.bindLong(1, x);
|
||||||
|
statement.bindLong(2, y);
|
||||||
|
statement.bindLong(3, 17 - zoom);
|
||||||
|
statement.bindLong(4, 0);
|
||||||
|
statement.bindBlob(5, buf.array());
|
||||||
|
statement.execute();
|
||||||
|
statement.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeDB(){
|
||||||
|
if(db != null){
|
||||||
|
db.close();
|
||||||
|
db = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean couldBeDownloadedFromInternet() {
|
||||||
|
if(getDatabase().isReadOnly() || base == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.couldBeDownloadedFromInternet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ import com.osmand.LogUtil;
|
||||||
import com.osmand.OsmandSettings;
|
import com.osmand.OsmandSettings;
|
||||||
import com.osmand.R;
|
import com.osmand.R;
|
||||||
import com.osmand.ResourceManager;
|
import com.osmand.ResourceManager;
|
||||||
|
import com.osmand.SQLiteTileSource;
|
||||||
import com.osmand.Version;
|
import com.osmand.Version;
|
||||||
import com.osmand.activities.FavouritesActivity.FavouritePoint;
|
import com.osmand.activities.FavouritesActivity.FavouritePoint;
|
||||||
import com.osmand.activities.FavouritesActivity.FavouritesDbHelper;
|
import com.osmand.activities.FavouritesActivity.FavouritesDbHelper;
|
||||||
|
@ -67,6 +68,7 @@ import com.osmand.data.preparation.MapTileDownloader;
|
||||||
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
|
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
|
||||||
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
||||||
import com.osmand.map.IMapLocationListener;
|
import com.osmand.map.IMapLocationListener;
|
||||||
|
import com.osmand.map.ITileSource;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.views.AnimateDraggingMapThread;
|
import com.osmand.views.AnimateDraggingMapThread;
|
||||||
|
@ -168,10 +170,10 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
public void tileDownloaded(DownloadRequest request) {
|
public void tileDownloaded(DownloadRequest request) {
|
||||||
if(request != null && !request.error && request.fileToSave != null){
|
if(request != null && !request.error && request.fileToSave != null){
|
||||||
ResourceManager mgr = ResourceManager.getResourceManager();
|
ResourceManager mgr = ResourceManager.getResourceManager();
|
||||||
String tile = mgr.calculateTileId(mapView.getMap(), request.xTile, request.yTile, request.zoom);
|
mgr.tileDownloaded(request);
|
||||||
mgr.tileDownloaded(tile);
|
|
||||||
}
|
}
|
||||||
mapView.tileDownloaded(request);
|
mapView.tileDownloaded(request);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -588,8 +590,13 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
||||||
|
|
||||||
// routing helper with current activity
|
// routing helper with current activity
|
||||||
routingHelper = RoutingHelper.getInstance(this);
|
routingHelper = RoutingHelper.getInstance(this);
|
||||||
if(mapView.getMap() != OsmandSettings.getMapTileSource(this)){
|
ITileSource source = OsmandSettings.getMapTileSource(this);
|
||||||
mapView.setMap(OsmandSettings.getMapTileSource(this));
|
if(!Algoritms.objectEquals(mapView.getMap(), source)){
|
||||||
|
if(mapView.getMap() instanceof SQLiteTileSource){
|
||||||
|
((SQLiteTileSource)mapView.getMap()).closeDB();
|
||||||
|
}
|
||||||
|
ResourceManager.getResourceManager().setMapSource(source);
|
||||||
|
mapView.setMap(source);
|
||||||
}
|
}
|
||||||
if(!OsmandSettings.isRotateMapToBearing(this)){
|
if(!OsmandSettings.isRotateMapToBearing(this)){
|
||||||
mapView.setRotate(0);
|
mapView.setRotate(0);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.osmand.activities;
|
package com.osmand.activities;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -34,6 +35,7 @@ import com.osmand.PoiFiltersHelper;
|
||||||
import com.osmand.ProgressDialogImplementation;
|
import com.osmand.ProgressDialogImplementation;
|
||||||
import com.osmand.R;
|
import com.osmand.R;
|
||||||
import com.osmand.ResourceManager;
|
import com.osmand.ResourceManager;
|
||||||
|
import com.osmand.SQLiteTileSource;
|
||||||
import com.osmand.OsmandSettings.ApplicationMode;
|
import com.osmand.OsmandSettings.ApplicationMode;
|
||||||
import com.osmand.activities.RouteProvider.RouteService;
|
import com.osmand.activities.RouteProvider.RouteService;
|
||||||
import com.osmand.map.TileSourceManager;
|
import com.osmand.map.TileSourceManager;
|
||||||
|
@ -101,6 +103,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
new BooleanPreference(OsmandSettings.SHOW_TRANSPORT_OVER_MAP, OsmandSettings.SHOW_TRANSPORT_OVER_MAP_DEF),
|
new BooleanPreference(OsmandSettings.SHOW_TRANSPORT_OVER_MAP, OsmandSettings.SHOW_TRANSPORT_OVER_MAP_DEF),
|
||||||
new BooleanPreference(OsmandSettings.SAVE_TRACK_TO_GPX, OsmandSettings.SAVE_TRACK_TO_GPX_DEF),
|
new BooleanPreference(OsmandSettings.SAVE_TRACK_TO_GPX, OsmandSettings.SAVE_TRACK_TO_GPX_DEF),
|
||||||
};
|
};
|
||||||
|
private BroadcastReceiver broadcastReceiver;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,13 +160,14 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
routeServiceEnabled.setOnPreferenceChangeListener(this);
|
routeServiceEnabled.setOnPreferenceChangeListener(this);
|
||||||
|
|
||||||
|
|
||||||
registerReceiver(new BroadcastReceiver(){
|
broadcastReceiver = new BroadcastReceiver(){
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
routeServiceEnabled.setChecked(false);
|
routeServiceEnabled.setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, new IntentFilter(NavigationService.OSMAND_STOP_SERVICE_ACTION));
|
};
|
||||||
|
registerReceiver(broadcastReceiver, new IntentFilter(NavigationService.OSMAND_STOP_SERVICE_ACTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -172,6 +176,12 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
updateAllSettings();
|
updateAllSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
unregisterReceiver(broadcastReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateAllSettings(){
|
public void updateAllSettings(){
|
||||||
SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||||
for(BooleanPreference b : booleanPreferences){
|
for(BooleanPreference b : booleanPreferences){
|
||||||
|
@ -291,13 +301,34 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
|
|
||||||
|
|
||||||
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
||||||
entries = new String[list.size()];
|
List<File> sqLiteFiles = new ArrayList<File>();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
entries[i] = list.get(i).getName();
|
File dir = new File(Environment.getExternalStorageDirectory(), ResourceManager.TILES_PATH);
|
||||||
|
if (dir != null) {
|
||||||
|
for (File f : dir.listFiles()) {
|
||||||
|
if (f.getName().endsWith(SQLiteTileSource.EXT)) {
|
||||||
|
sqLiteFiles.add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entries = new String[list.size() + sqLiteFiles.size()];
|
||||||
|
valueEntries = new String[list.size() + sqLiteFiles.size()];
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
entries[i + sqLiteFiles.size()] = list.get(i).getName();
|
||||||
|
valueEntries[i + sqLiteFiles.size()] = list.get(i).getName();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < sqLiteFiles.size(); i++) {
|
||||||
|
String n = sqLiteFiles.get(i).getName();
|
||||||
|
entries[i] = n.substring(0, n.indexOf('.'));
|
||||||
|
valueEntries[i] = sqLiteFiles.get(i).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tileSourcePreference.setEntries(entries);
|
tileSourcePreference.setEntries(entries);
|
||||||
tileSourcePreference.setEntryValues(entries);
|
tileSourcePreference.setEntryValues(valueEntries);
|
||||||
tileSourcePreference.setValue(OsmandSettings.getMapTileSourceName(this));
|
tileSourcePreference.setValue(OsmandSettings.getMapTileSourceName(this));
|
||||||
String mapName = " " +OsmandSettings.getMapTileSourceName(this); //$NON-NLS-1$
|
String mapName = " " +OsmandSettings.getMapTileSourceName(this); //$NON-NLS-1$
|
||||||
String summary = tileSourcePreference.getSummary().toString();
|
String summary = tileSourcePreference.getSummary().toString();
|
||||||
|
|
|
@ -424,7 +424,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
Canvas canvas = holder.lockCanvas();
|
Canvas canvas = holder.lockCanvas();
|
||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
ResourceManager mgr = ResourceManager.getResourceManager();
|
ResourceManager mgr = ResourceManager.getResourceManager();
|
||||||
boolean useInternet = OsmandSettings.isUsingInternetToDownloadTiles(getContext());
|
boolean useInternet = OsmandSettings.isUsingInternetToDownloadTiles(getContext()) && map.couldBeDownloadedFromInternet();
|
||||||
int maxLevel = OsmandSettings.getMaximumLevelToDownloadTile(getContext());
|
int maxLevel = OsmandSettings.getMaximumLevelToDownloadTile(getContext());
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.rotate(rotate, w , h);
|
canvas.rotate(rotate, w , h);
|
||||||
|
@ -441,7 +441,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
float y1 = (j + top - tileY) * ftileSize + h;
|
float y1 = (j + top - tileY) * ftileSize + h;
|
||||||
String ordImgTile = mgr.calculateTileId(map, left + i, top + j, nzoom);
|
String ordImgTile = mgr.calculateTileId(map, left + i, top + j, nzoom);
|
||||||
// asking tile image async
|
// asking tile image async
|
||||||
boolean imgExist = mgr.tileExistOnFileSystem(ordImgTile);
|
boolean imgExist = mgr.tileExistOnFileSystem(ordImgTile, map, left + i, top + j, nzoom);
|
||||||
Bitmap bmp = null;
|
Bitmap bmp = null;
|
||||||
boolean originalBeLoaded = useInternet && nzoom <= maxLevel;
|
boolean originalBeLoaded = useInternet && nzoom <= maxLevel;
|
||||||
if (imgExist || originalBeLoaded) {
|
if (imgExist || originalBeLoaded) {
|
||||||
|
@ -461,10 +461,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!originalBeLoaded && !imgExist){
|
if(!originalBeLoaded && !imgExist){
|
||||||
if (mgr.tileExistOnFileSystem(imgTile2) || (useInternet && nzoom - 1 <= maxLevel)) {
|
if (mgr.tileExistOnFileSystem(imgTile2, map, (left + i) / 2, (top + j) / 2, nzoom - 1) || (useInternet && nzoom - 1 <= maxLevel)) {
|
||||||
bmp = mgr.getTileImageForMapAsync(imgTile2, map, (left + i) / 2, (top + j) / 2, nzoom - 1, useInternet);
|
bmp = mgr.getTileImageForMapAsync(imgTile2, map, (left + i) / 2, (top + j) / 2, nzoom - 1, useInternet);
|
||||||
div = 2;
|
div = 2;
|
||||||
} else if (mgr.tileExistOnFileSystem(imgTile4) || (useInternet && nzoom - 2 <= maxLevel)) {
|
} else if (mgr.tileExistOnFileSystem(imgTile4, map, (left + i) / 4, (top + j) / 4, nzoom - 2) || (useInternet && nzoom - 2 <= maxLevel)) {
|
||||||
bmp = mgr.getTileImageForMapAsync(imgTile4, map, (left + i) / 4, (top + j) / 4, nzoom - 2, useInternet);
|
bmp = mgr.getTileImageForMapAsync(imgTile4, map, (left + i) / 4, (top + j) / 4, nzoom - 2, useInternet);
|
||||||
div = 4;
|
div = 4;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue