Merge branch 'master' of git@github.com:osmandapp/Osmand.git

This commit is contained in:
sonora 2011-08-27 17:50:20 +02:00
commit e43fb08a65
15 changed files with 548 additions and 395 deletions

View file

@ -815,17 +815,17 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.executeUpdate("create table city (id bigint primary key, latitude double, longitude double, " + stat.executeUpdate("create table city (id bigint primary key, latitude double, longitude double, " +
"name varchar(255), name_en varchar(255), city_type varchar(32))"); "name varchar(1024), name_en varchar(1024), city_type varchar(32))");
stat.executeUpdate("create index city_ind on city (id, city_type)"); stat.executeUpdate("create index city_ind on city (id, city_type)");
stat.executeUpdate("create table street (id bigint primary key, latitude double, longitude double, " + stat.executeUpdate("create table street (id bigint primary key, latitude double, longitude double, " +
"name varchar(255), name_en varchar(255), city bigint)"); "name varchar(1024), name_en varchar(1024), city bigint)");
stat.executeUpdate("create index street_city on street (city)"); stat.executeUpdate("create index street_city on street (city)");
stat.executeUpdate("create index street_id on street (id)"); stat.executeUpdate("create index street_id on street (id)");
// create index on name ? // create index on name ?
stat.executeUpdate("create table building (id bigint, latitude double, longitude double, " + stat.executeUpdate("create table building (id bigint, latitude double, longitude double, " +
"name varchar(255), name_en varchar(255), street bigint, postcode varchar(255), primary key(street, id))"); "name varchar(1024), name_en varchar(1024), street bigint, postcode varchar(1024), primary key(street, id))");
stat.executeUpdate("create index building_postcode on building (postcode)"); stat.executeUpdate("create index building_postcode on building (postcode)");
stat.executeUpdate("create index building_street on building (street)"); stat.executeUpdate("create index building_street on building (street)");
stat.executeUpdate("create index building_id on building (id)"); stat.executeUpdate("create index building_id on building (id)");

View file

@ -339,8 +339,8 @@ public class IndexCreator {
public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter, MapZooms mapZooms, public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter, MapZooms mapZooms,
MapRenderingTypes renderingTypes) throws IOException, SAXException, SQLException { MapRenderingTypes renderingTypes) throws IOException, SAXException, SQLException {
if(LevelDBAccess.load()){ if(!LevelDBAccess.load() && dialect == DBDialect.NOSQL){
dialect = DBDialect.NOSQL; dialect = DBDialect.SQLITE;
} }
if (renderingTypes == null) { if (renderingTypes == null) {

View file

@ -119,8 +119,8 @@ public class IndexPoiCreator extends AbstractIndexPartCreator {
// create database structure // create database structure
Statement stat = poiConnection.createStatement(); Statement stat = poiConnection.createStatement();
stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$ stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$
"(id bigint, x int, y int, name_en varchar(255), name varchar(255), " + "(id bigint, x int, y int, name_en varchar(1024), name varchar(1024), " +
"type varchar(255), subtype varchar(255), opening_hours varchar(255), phone varchar(255), site varchar(255)," + "type varchar(1024), subtype varchar(1024), opening_hours varchar(1024), phone varchar(1024), site varchar(1024)," +
"primary key(id, type, subtype))"); "primary key(id, type, subtype))");
stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)"); stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)");
stat.executeUpdate("create index poi_id on poi (id, type, subtype)"); stat.executeUpdate("create index poi_id on poi (id, type, subtype)");

View file

@ -141,15 +141,15 @@ public class IndexTransportCreator extends AbstractIndexPartCreator {
public void createDatabaseStructure(Connection conn, DBDialect dialect, String rtreeStopsFileName) throws SQLException, IOException{ public void createDatabaseStructure(Connection conn, DBDialect dialect, String rtreeStopsFileName) throws SQLException, IOException{
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.executeUpdate("create table transport_route (id bigint primary key, type varchar(255), operator varchar(255)," + stat.executeUpdate("create table transport_route (id bigint primary key, type varchar(1024), operator varchar(1024)," +
"ref varchar(255), name varchar(255), name_en varchar(255), dist int)"); "ref varchar(1024), name varchar(1024), name_en varchar(1024), dist int)");
stat.executeUpdate("create index transport_route_id on transport_route (id)"); stat.executeUpdate("create index transport_route_id on transport_route (id)");
stat.executeUpdate("create table transport_route_stop (stop bigint, route bigint, ord int, direction smallint, primary key (route, ord, direction))"); stat.executeUpdate("create table transport_route_stop (stop bigint, route bigint, ord int, direction smallint, primary key (route, ord, direction))");
stat.executeUpdate("create index transport_route_stop_stop on transport_route_stop (stop)"); stat.executeUpdate("create index transport_route_stop_stop on transport_route_stop (stop)");
stat.executeUpdate("create index transport_route_stop_route on transport_route_stop (route)"); stat.executeUpdate("create index transport_route_stop_route on transport_route_stop (route)");
stat.executeUpdate("create table transport_stop (id bigint primary key, latitude double, longitude double, name varchar(255), name_en varchar(255))"); stat.executeUpdate("create table transport_stop (id bigint primary key, latitude double, longitude double, name varchar(1024), name_en varchar(1024))");
stat.executeUpdate("create index transport_stop_id on transport_stop (id)"); stat.executeUpdate("create index transport_stop_id on transport_stop (id)");
stat.executeUpdate("create index transport_stop_location on transport_stop (latitude, longitude)"); stat.executeUpdate("create index transport_stop_location on transport_stop (latitude, longitude)");

View file

@ -773,12 +773,12 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
private void createMapIndexStructure(Connection conn) throws SQLException{ private void createMapIndexStructure(Connection conn) throws SQLException{
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.executeUpdate("create table binary_map_objects (id bigint primary key, name varchar(255), " + stat.executeUpdate("create table binary_map_objects (id bigint primary key, name varchar(1024), " +
"types binary, restrictions binary, nodes binary, highway int)"); "types binary, restrictions binary, nodes binary, highway int)");
stat.executeUpdate("create index binary_map_objects_ind on binary_map_objects (id)"); stat.executeUpdate("create index binary_map_objects_ind on binary_map_objects (id)");
stat.executeUpdate("create table low_level_map_objects (id bigint primary key, start_node bigint, " + stat.executeUpdate("create table low_level_map_objects (id bigint primary key, start_node bigint, " +
"end_node bigint, name varchar(255), nodes binary, type bigint, level smallint)"); "end_node bigint, name varchar(1024), nodes binary, type bigint, level smallint)");
stat.executeUpdate("create index low_level_map_objects_ind on low_level_map_objects (id)"); stat.executeUpdate("create index low_level_map_objects_ind on low_level_map_objects (id)");
stat.executeUpdate("create index low_level_map_objects_ind_st on low_level_map_objects (start_node, type)"); stat.executeUpdate("create index low_level_map_objects_ind_st on low_level_map_objects (start_node, type)");
stat.executeUpdate("create index low_level_map_objects_ind_end on low_level_map_objects (end_node, type)"); stat.executeUpdate("create index low_level_map_objects_ind_end on low_level_map_objects (end_node, type)");

View file

@ -210,9 +210,9 @@ public class OsmDbAccessor implements OsmDbAccessorContext {
String select; String select;
int count = 0; int count = 0;
// stat.executeUpdate("create table tags (id "+longType+", type smallint, skeys varchar(255), value varchar(255))"); // stat.executeUpdate("create table tags (id "+longType+", type smallint, skeys varchar(1024), value varchar(1024))");
// stat.executeUpdate("create table ways (id "+longType+", node "+longType+", ord smallint)"); // stat.executeUpdate("create table ways (id "+longType+", node "+longType+", ord smallint)");
// stat.executeUpdate("create table relations (id "+longType+", member "+longType+", type smallint, role varchar(255), ord smallint)"); // stat.executeUpdate("create table relations (id "+longType+", member "+longType+", type smallint, role varchar(1024), ord smallint)");
if (type == EntityType.NODE) { if (type == EntityType.NODE) {
// filter out all nodes without tags // filter out all nodes without tags
select = "select n.id, n.latitude, n.longitude, t.skeys, t.value from node n inner join tags t on n.id = t.id and t.type = 0 order by n.id"; //$NON-NLS-1$ select = "select n.id, n.latitude, n.longitude, t.skeys, t.value from node n inner join tags t on n.id = t.id and t.type = 0 order by n.id"; //$NON-NLS-1$

View file

@ -76,10 +76,10 @@ public class OsmDbCreator implements IOsmStorageFilter {
stat.executeUpdate("create table ways (id bigint, node bigint, ord smallint, primary key (id, ord))"); //$NON-NLS-1$ stat.executeUpdate("create table ways (id bigint, node bigint, ord smallint, primary key (id, ord))"); //$NON-NLS-1$
stat.executeUpdate("create index IdWIndex ON ways (id)"); //$NON-NLS-1$ stat.executeUpdate("create index IdWIndex ON ways (id)"); //$NON-NLS-1$
dialect.deleteTableIfExists("relations", stat); dialect.deleteTableIfExists("relations", stat);
stat.executeUpdate("create table relations (id bigint, member bigint, type smallint, role varchar(255), ord smallint, primary key (id, ord))"); //$NON-NLS-1$ stat.executeUpdate("create table relations (id bigint, member bigint, type smallint, role varchar(1024), ord smallint, primary key (id, ord))"); //$NON-NLS-1$
stat.executeUpdate("create index IdRIndex ON relations (id)"); //$NON-NLS-1$ stat.executeUpdate("create index IdRIndex ON relations (id)"); //$NON-NLS-1$
dialect.deleteTableIfExists("tags", stat); dialect.deleteTableIfExists("tags", stat);
stat.executeUpdate("create table tags (id bigint, type smallint, skeys varchar(255), value varchar(255), primary key (id, type, skeys))"); //$NON-NLS-1$ stat.executeUpdate("create table tags (id bigint, type smallint, skeys varchar(1024), value varchar(1024), primary key (id, type, skeys))"); //$NON-NLS-1$
stat.executeUpdate("create index IdTIndex ON tags (id, type)"); //$NON-NLS-1$ stat.executeUpdate("create index IdTIndex ON tags (id, type)"); //$NON-NLS-1$
stat.close(); stat.close();

View file

@ -47,7 +47,7 @@
<subtype id="36" point="true" tag="highway" value="stop" minzoom="15" /> <subtype id="36" point="true" tag="highway" value="stop" minzoom="15" />
<subtype id="37" point="true" tag="highway" value="give_way" minzoom="15" /> <subtype id="37" point="true" tag="highway" value="give_way" minzoom="15" />
<subtype id="38" point="true" tag="highway" value="traffic_signals" minzoom="15" /> <subtype id="38" point="true" tag="highway" value="traffic_signals" minzoom="15" />
<subtype id="39" point="true" tag="highway" value="motorway_junction" minzoom="15" /> <subtype id="39" point="true" tag="highway" value="motorway_junction" minzoom="13" />
<subtype id="40" point="true" tag="highway" value="bus_stop" minzoom="15" /> <subtype id="40" point="true" tag="highway" value="bus_stop" minzoom="15" />
<subtype id="41" point="true" tag="highway" value="platform" minzoom="15" /> <subtype id="41" point="true" tag="highway" value="platform" minzoom="15" />
<subtype id="42" point="true" tag="highway" value="turning_circle" minzoom="15" /> <subtype id="42" point="true" tag="highway" value="turning_circle" minzoom="15" />

View file

@ -2,7 +2,7 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical" android:keepScreenOn="true"> android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/MainLayout">
<TextView android:id="@+id/Label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/select_index_file_to_download"></TextView> <TextView android:id="@+id/Label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/select_index_file_to_download"></TextView>

View file

@ -0,0 +1,240 @@
package net.osmand.plus.activities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.logging.Log;
import android.app.Activity;
import android.graphics.drawable.Drawable.Callback;
import android.os.AsyncTask;
import android.widget.Toast;
import net.osmand.IProgress;
import net.osmand.LogUtil;
import net.osmand.data.IndexConstants;
import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
public class DownloadFileHelper {
private final static Log log = LogUtil.getLog(DownloadFileHelper.class);
private static final int BUFFER_SIZE = 32256;
protected final int TRIES_TO_DOWNLOAD = 15;
protected final long TIMEOUT_BETWEEN_DOWNLOADS = 8000;
private final Activity ctx;
private boolean interruptDownloading = false;
public DownloadFileHelper(Activity ctx){
this.ctx = ctx;
}
public interface DownloadFileShowWarning {
public void showWarning(String warning);
}
protected void downloadFile(String fileName, FileOutputStream out, URL url, String part, String indexOfAllFiles,
IProgress progress) throws IOException, InterruptedException {
InputStream is = null;
byte[] buffer = new byte[BUFFER_SIZE];
int read = 0;
int length = 0;
int fileread = 0;
int triesDownload = TRIES_TO_DOWNLOAD;
boolean first = true;
try {
while (triesDownload > 0) {
try {
if (!first) {
log.info("Reconnecting"); //$NON-NLS-1$
try {
Thread.sleep(TIMEOUT_BETWEEN_DOWNLOADS);
} catch (InterruptedException e) {
}
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000);
if (fileread > 0) {
String range = "bytes="+fileread + "-" + (length -1); //$NON-NLS-1$ //$NON-NLS-2$
conn.setRequestProperty("Range", range); //$NON-NLS-1$
}
conn.setConnectTimeout(30000);
log.info(conn.getResponseMessage() + " " + conn.getResponseCode()); //$NON-NLS-1$
if (conn.getResponseCode() != HttpURLConnection.HTTP_PARTIAL &&
conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
conn.disconnect();
triesDownload--;
continue;
}
is = conn.getInputStream();
// long skipped = 0;
// while (skipped < fileread) {
// skipped += is.skip(fileread - skipped);
// }
if (first) {
length = conn.getContentLength();
String taskName = ctx.getString(R.string.downloading_file) + indexOfAllFiles +" " + fileName;
if(part != null){
taskName += part;
}
progress.startTask(taskName, length); //$NON-NLS-1$
}
first = false;
while ((read = is.read(buffer)) != -1) {
if(interruptDownloading){
throw new InterruptedException();
}
out.write(buffer, 0, read);
progress.progress(read);
fileread += read;
}
if(length <= fileread){
triesDownload = 0;
}
} catch (IOException e) {
log.error("IOException", e); //$NON-NLS-1$
triesDownload--;
}
}
} finally {
if (is != null) {
is.close();
}
}
if(length != fileread || length == 0){
throw new IOException("File was not fully read"); //$NON-NLS-1$
}
}
protected boolean downloadFile(final String fileName, final File fileToDownload, final File fileToUnZip, final boolean unzipToDir,
IProgress progress, Long dateModified, int parts, List<File> toReIndex, String indexOfAllFiles,
DownloadFileShowWarning showWarningCallback) throws InterruptedException {
FileOutputStream out = null;
try {
out = new FileOutputStream(fileToDownload);
try {
if(parts == 1){
URL url = new URL("http://download.osmand.net/download?file="+fileName); //$NON-NLS-1$
downloadFile(fileName, out, url, null, indexOfAllFiles, progress);
} else {
for(int i=1; i<=parts; i++){
URL url = new URL("http://download.osmand.net/download?file="+fileName+"-"+i); //$NON-NLS-1$
downloadFile(fileName, out, url, " ["+i+"/"+parts+"]", indexOfAllFiles, progress);
}
}
} finally {
out.close();
out = null;
}
File toIndex = fileToDownload;
if (fileToDownload.getName().endsWith(".zip")) { //$NON-NLS-1$
progress.startTask(ctx.getString(R.string.unzipping_file), -1);
if (!unzipToDir) {
toIndex = fileToUnZip;
} else {
fileToUnZip.mkdirs();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(fileToDownload));
ZipEntry entry = null;
boolean first = true;
while ((entry = zipIn.getNextEntry()) != null) {
File fs;
if (!unzipToDir) {
if (first) {
fs = toIndex;
first = false;
} else {
String name = entry.getName();
// small simplification
int ind = name.lastIndexOf('_');
if (ind > 0) {
// cut version
int i = name.indexOf('.', ind);
if (i > 0) {
name = name.substring(0, ind) + name.substring(i, name.length());
}
}
fs = new File(fileToUnZip.getParent(), name);
toIndex = fs;
}
} else {
fs = new File(fileToUnZip, entry.getName());
}
out = new FileOutputStream(fs);
int read;
byte[] buffer = new byte[BUFFER_SIZE];
while ((read = zipIn.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
}
zipIn.close();
fileToDownload.delete(); // zip is no needed more
}
ArrayList<String> warnings = new ArrayList<String>();
ResourceManager manager = ((OsmandApplication) ctx.getApplicationContext()).getResourceManager();
if(dateModified != null){
toIndex.setLastModified(dateModified);
}
if (toIndex.getName().endsWith(IndexConstants.POI_INDEX_EXT)) {
// update poi index immediately
manager.indexingPoi(progress, warnings, toIndex);
}
if(dateModified != null){
toIndex.setLastModified(dateModified);
manager.updateIndexLastDateModified(toIndex);
}
toReIndex.add(toIndex);
if (warnings.isEmpty()) {
showWarningCallback.showWarning(ctx.getString(R.string.download_index_success));
} else {
showWarningCallback.showWarning(warnings.get(0));
}
return true;
} catch (IOException e) {
log.error("Exception ocurred", e); //$NON-NLS-1$
showWarningCallback.showWarning(ctx.getString(R.string.error_io_error));
if(out != null){
try {
out.close();
} catch (IOException e1) {
}
}
// Possibly file is corrupted
fileToDownload.delete();
return false;
} catch (InterruptedException e) {
// Possibly file is corrupted
fileToDownload.delete();
throw e;
}
}
public void setInterruptDownloading(boolean interruptDownloading) {
this.interruptDownloading = interruptDownloading;
}
public boolean isInterruptDownloading() {
return interruptDownloading;
}
}

View file

@ -12,13 +12,7 @@ import static net.osmand.data.IndexConstants.VOICE_VERSION;
import static net.osmand.data.IndexConstants.TTSVOICE_VERSION; import static net.osmand.data.IndexConstants.TTSVOICE_VERSION;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -33,11 +27,8 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.LogUtil;
import net.osmand.data.IndexConstants; import net.osmand.data.IndexConstants;
import net.osmand.plus.DownloadOsmandIndexesHelper; import net.osmand.plus.DownloadOsmandIndexesHelper;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
@ -45,8 +36,8 @@ import net.osmand.plus.ProgressDialogImplementation;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.ResourceManager; import net.osmand.plus.ResourceManager;
import net.osmand.plus.DownloadOsmandIndexesHelper.IndexItem; import net.osmand.plus.DownloadOsmandIndexesHelper.IndexItem;
import net.osmand.plus.activities.DownloadFileHelper.DownloadFileShowWarning;
import org.apache.commons.logging.Log;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ListActivity; import android.app.ListActivity;
@ -55,6 +46,7 @@ import android.app.AlertDialog.Builder;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -74,37 +66,25 @@ import android.widget.Toast;
public class DownloadIndexActivity extends ListActivity { public class DownloadIndexActivity extends ListActivity {
private final static Log log = LogUtil.getLog(DownloadIndexActivity.class);
private static final int RELOAD_ID = 0; private static final int RELOAD_ID = 0;
private static final int SELECT_ALL_ID = 1; private static final int SELECT_ALL_ID = 1;
private static final int DESELECT_ALL_ID = 2; private static final int DESELECT_ALL_ID = 2;
private static final int FILTER_EXISTING_REGIONS = 3; private static final int FILTER_EXISTING_REGIONS = 3;
private static final int MB = 1 << 20;
public static final String FILTER_KEY = "filter";
private static DownloadIndexListThread downloadListIndexThread = new DownloadIndexListThread(); private static DownloadIndexListThread downloadListIndexThread = new DownloadIndexListThread();
private ProgressDialog progressFileDlg = null; private ProgressDialog progressFileDlg = null;
private ProgressDialog progressListDlg = null; private ProgressDialog progressListDlg = null;
private Map<String, String> indexFileNames = null; private Map<String, String> indexFileNames = null;
private TreeMap<String, DownloadEntry> entriesToDownload = new TreeMap<String, DownloadEntry>(); private TreeMap<String, DownloadEntry> entriesToDownload = new TreeMap<String, DownloadEntry>();
private TextWatcher textWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) { private TextWatcher textWatcher ;
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
DownloadIndexAdapter adapter = ((DownloadIndexAdapter)getListAdapter());
if(adapter != null){
adapter.getFilter().filter(s);
}
}
};
private EditText filterText; private EditText filterText;
private DownloadFileHelper downloadFileHelper = null;
@Override @Override
@ -112,11 +92,12 @@ public class DownloadIndexActivity extends ListActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// recreation upon rotation is prevented in manifest file // recreation upon rotation is prevented in manifest file
setContentView(R.layout.download_index); setContentView(R.layout.download_index);
downloadFileHelper = new DownloadFileHelper(this);
findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener(){ findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener(){
@Override @Override
public void onClick(View v) { public void onClick(View v) {
downloadFiles(); downloadFilesConfirmation();
} }
}); });
@ -124,6 +105,22 @@ public class DownloadIndexActivity extends ListActivity {
indexFileNames = ((OsmandApplication)getApplication()).getResourceManager().getIndexFileNames(); indexFileNames = ((OsmandApplication)getApplication()).getResourceManager().getIndexFileNames();
filterText = (EditText) findViewById(R.id.search_box); filterText = (EditText) findViewById(R.id.search_box);
textWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
DownloadIndexAdapter adapter = ((DownloadIndexAdapter)getListAdapter());
if(adapter != null){
adapter.getFilter().filter(s);
}
}
};
filterText.addTextChangedListener(textWatcher); filterText.addTextChangedListener(textWatcher);
final Intent intent = getIntent(); final Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) { if (intent != null && intent.getExtras() != null) {
@ -251,11 +248,6 @@ public class DownloadIndexActivity extends ListActivity {
} }
private final static int MB = 1 << 20;
@Override @Override
protected void onListItemClick(ListView l, View v, int position, long id) { protected void onListItemClick(ListView l, View v, int position, long id) {
@ -420,7 +412,7 @@ public class DownloadIndexActivity extends ListActivity {
return entry; return entry;
} }
protected void downloadFiles() { protected void downloadFilesConfirmation() {
Builder builder = new AlertDialog.Builder(this); Builder builder = new AlertDialog.Builder(this);
double sz = 0; double sz = 0;
for(DownloadEntry es : entriesToDownload.values()){ for(DownloadEntry es : entriesToDownload.values()){
@ -430,181 +422,20 @@ public class DownloadIndexActivity extends ListActivity {
builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
progressFileDlg = ProgressDialog.show(DownloadIndexActivity.this, getString(R.string.downloading), DownloadIndexesAsyncTask task = new DownloadIndexesAsyncTask();
getString(R.string.downloading_file), true, true); task.execute(entriesToDownload.keySet().toArray(new String[0]));
interruptDownloading = false;
progressFileDlg.show();
final ProgressDialogImplementation impl = new ProgressDialogImplementation(progressFileDlg, true);
progressFileDlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
interruptDownloading = true;
}
});
impl.setRunnable("DownloadIndex", new Runnable() { //$NON-NLS-1$
@Override
public void run() {
try {
List<File> filesToReindex = new ArrayList<File>();
ArrayList<String> filesToDownload = new ArrayList<String>(entriesToDownload.keySet());
for(int i=0;i<filesToDownload.size(); i++) {
String filename = filesToDownload.get(i);
DownloadEntry entry = entriesToDownload.get(filename);
if (entry != null) {
String indexOfAllFiles = filesToDownload.size() <= 1 ? "" : (" ["+(i+1)+"/"+filesToDownload.size()+"]");
if (downloadFile(filename, entry.fileToSave, entry.fileToUnzip, entry.unzip, impl, entry.dateModified,
entry.parts, filesToReindex, indexOfAllFiles)) {
entriesToDownload.remove(filename);
runOnUiThread(new Runnable() {
@Override
public void run() {
((DownloadIndexAdapter) getListAdapter()).notifyDataSetChanged();
findViewById(R.id.DownloadButton).setVisibility(entriesToDownload.isEmpty() ? View.GONE : View.VISIBLE);
}
});
}
}
}
boolean vectorMapsToReindex = false;
for(File f : filesToReindex){
if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
vectorMapsToReindex = true;
break;
}
}
// reindex vector maps all at one time
if (vectorMapsToReindex) {
ResourceManager manager = ((OsmandApplication) getApplication()).getResourceManager();
List<String> warnings = manager.indexingMaps(impl);
if(warnings.isEmpty() && !OsmandSettings.getOsmandSettings(getApplicationContext()).MAP_VECTOR_DATA.get()){
warnings.add(getString(R.string.binary_map_download_success));
// Is it proper way to switch every tome to vector data?
OsmandSettings.getOsmandSettings(getApplicationContext()).MAP_VECTOR_DATA.set(true);
}
if (!warnings.isEmpty()) {
showWarning(warnings.get(0));
}
}
} catch (InterruptedException e) {
// do not dismiss dialog
progressFileDlg = null;
} finally {
if (progressFileDlg != null) {
progressFileDlg.dismiss();
progressFileDlg = null;
}
}
}
});
impl.run();
} }
}); });
builder.setNegativeButton(R.string.default_buttons_no, null); builder.setNegativeButton(R.string.default_buttons_no, null);
builder.show(); builder.show();
} }
private static final int BUFFER_SIZE = 32256;
public static final String FILTER_KEY = "filter";
private static class DownloadEntry {
public File fileToSave;
public File fileToUnzip;
public boolean unzip;
public Long dateModified;
public double sizeMB;
public String baseName;
public int parts;
}
protected final int TRIES_TO_DOWNLOAD = 15;
protected final long TIMEOUT_BETWEEN_DOWNLOADS = 8000;
private boolean interruptDownloading = false;
protected void downloadFile(String fileName, FileOutputStream out, URL url, String part, String indexOfAllFiles,
IProgress progress) throws IOException, InterruptedException {
InputStream is = null;
byte[] buffer = new byte[BUFFER_SIZE];
int read = 0;
int length = 0;
int fileread = 0;
int triesDownload = TRIES_TO_DOWNLOAD;
boolean first = true;
try {
while (triesDownload > 0) {
try {
if (!first) {
log.info("Reconnecting"); //$NON-NLS-1$
try {
Thread.sleep(TIMEOUT_BETWEEN_DOWNLOADS);
} catch (InterruptedException e) {
}
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000);
if (fileread > 0) {
String range = "bytes="+fileread + "-" + (length -1); //$NON-NLS-1$ //$NON-NLS-2$
conn.setRequestProperty("Range", range); //$NON-NLS-1$
}
conn.setConnectTimeout(30000);
log.info(conn.getResponseMessage() + " " + conn.getResponseCode()); //$NON-NLS-1$
if (conn.getResponseCode() != HttpURLConnection.HTTP_PARTIAL &&
conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
conn.disconnect();
triesDownload--;
continue;
}
is = conn.getInputStream();
// long skipped = 0;
// while (skipped < fileread) {
// skipped += is.skip(fileread - skipped);
// }
if (first) {
length = conn.getContentLength();
String taskName = getString(R.string.downloading_file) + indexOfAllFiles +" " + fileName;
if(part != null){
taskName += part;
}
progress.startTask(taskName, length); //$NON-NLS-1$
}
first = false;
while ((read = is.read(buffer)) != -1) {
if(interruptDownloading){
throw new InterruptedException();
}
out.write(buffer, 0, read);
progress.progress(read);
fileread += read;
}
if(length <= fileread){
triesDownload = 0;
}
} catch (IOException e) {
log.error("IOException", e); //$NON-NLS-1$
triesDownload--;
}
}
} finally {
if (is != null) {
is.close();
}
}
if(length != fileread || length == 0){
throw new IOException("File was not fully read"); //$NON-NLS-1$
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if(isFinishing()){ if(isFinishing()){
interruptDownloading = true; downloadFileHelper.setInterruptDownloading(true);
} }
if (textWatcher != null) { if (textWatcher != null) {
EditText filterText = (EditText) findViewById(R.id.search_box); EditText filterText = (EditText) findViewById(R.id.search_box);
@ -614,122 +445,6 @@ public class DownloadIndexActivity extends ListActivity {
progressFileDlg = null; progressFileDlg = null;
} }
protected boolean downloadFile(final String fileName, final File fileToDownload, final File fileToUnZip, final boolean unzipToDir,
IProgress progress, Long dateModified, int parts, List<File> toReIndex, String indexOfAllFiles) throws InterruptedException {
FileOutputStream out = null;
try {
out = new FileOutputStream(fileToDownload);
try {
if(parts == 1){
URL url = new URL("http://download.osmand.net/download?file="+fileName); //$NON-NLS-1$
downloadFile(fileName, out, url, null, indexOfAllFiles, progress);
} else {
for(int i=1; i<=parts; i++){
URL url = new URL("http://download.osmand.net/download?file="+fileName+"-"+i); //$NON-NLS-1$
downloadFile(fileName, out, url, " ["+i+"/"+parts+"]", indexOfAllFiles, progress);
}
}
} finally {
out.close();
out = null;
}
File toIndex = fileToDownload;
if (fileToDownload.getName().endsWith(".zip")) { //$NON-NLS-1$
progress.startTask(getString(R.string.unzipping_file), -1);
if (!unzipToDir) {
toIndex = fileToUnZip;
} else {
fileToUnZip.mkdirs();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(fileToDownload));
ZipEntry entry = null;
boolean first = true;
while ((entry = zipIn.getNextEntry()) != null) {
File fs;
if (!unzipToDir) {
if (first) {
fs = toIndex;
first = false;
} else {
String name = entry.getName();
// small simplification
int ind = name.lastIndexOf('_');
if (ind > 0) {
// cut version
int i = name.indexOf('.', ind);
if (i > 0) {
name = name.substring(0, ind) + name.substring(i, name.length());
}
}
fs = new File(fileToUnZip.getParent(), name);
toIndex = fs;
}
} else {
fs = new File(fileToUnZip, entry.getName());
}
out = new FileOutputStream(fs);
int read;
byte[] buffer = new byte[BUFFER_SIZE];
while ((read = zipIn.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
}
zipIn.close();
fileToDownload.delete(); // zip is no needed more
}
ArrayList<String> warnings = new ArrayList<String>();
ResourceManager manager = ((OsmandApplication) getApplication()).getResourceManager();
if(dateModified != null){
toIndex.setLastModified(dateModified);
}
if (toIndex.getName().endsWith(IndexConstants.POI_INDEX_EXT)) {
// update poi index immediately
manager.indexingPoi(progress, warnings, toIndex);
}
if(dateModified != null){
toIndex.setLastModified(dateModified);
manager.updateIndexLastDateModified(toIndex);
}
toReIndex.add(toIndex);
if (warnings.isEmpty()) {
showWarning(getString(R.string.download_index_success));
} else {
showWarning(warnings.get(0));
}
return true;
} catch (IOException e) {
log.error("Exception ocurred", e); //$NON-NLS-1$
showWarning(getString(R.string.error_io_error));
if(out != null){
try {
out.close();
} catch (IOException e1) {
}
}
// Possibly file is corrupted
fileToDownload.delete();
return false;
} catch (InterruptedException e) {
// Possibly file is corrupted
fileToDownload.delete();
throw e;
}
}
public void showWarning(final String messages){
runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(DownloadIndexActivity.this, messages, Toast.LENGTH_LONG).show();
}
});
}
private String convertServerFileNameToLocal(String name){ private String convertServerFileNameToLocal(String name){
int l = name.lastIndexOf('_'); int l = name.lastIndexOf('_');
@ -743,6 +458,124 @@ public class DownloadIndexActivity extends ListActivity {
} }
return name.substring(0, l) + s; return name.substring(0, l) + s;
} }
private class DownloadIndexesAsyncTask extends AsyncTask<String, Object, String> implements DownloadFileShowWarning {
private IProgress progress;
@Override
protected void onProgressUpdate(Object... values) {
for(Object o : values){
if(o instanceof DownloadEntry){
((DownloadIndexAdapter) getListAdapter()).notifyDataSetChanged();
findViewById(R.id.DownloadButton).setVisibility(
entriesToDownload.isEmpty() ? View.GONE : View.VISIBLE);
} else if(o instanceof String) {
Toast.makeText(DownloadIndexActivity.this, (String) o, Toast.LENGTH_LONG).show();
}
}
super.onProgressUpdate(values);
}
@Override
protected void onPreExecute() {
progressFileDlg = ProgressDialog.show(DownloadIndexActivity.this, getString(R.string.downloading),
getString(R.string.downloading_file), true, true);
downloadFileHelper.setInterruptDownloading(false);
progressFileDlg.show();
progress = new ProgressDialogImplementation(progressFileDlg, true);
progressFileDlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
downloadFileHelper.setInterruptDownloading(true);
}
});
View mainView = findViewById(R.id.MainLayout);
if(mainView != null){
mainView.setKeepScreenOn(true);
}
}
@Override
protected void onPostExecute(String result) {
if(result != null){
Toast.makeText(DownloadIndexActivity.this, result, Toast.LENGTH_LONG).show();
}
View mainView = findViewById(R.id.MainLayout);
if(mainView != null){
mainView.setKeepScreenOn(false);
}
}
@Override
protected String doInBackground(String... filesToDownload) {
try {
List<File> filesToReindex = new ArrayList<File>();
for (int i = 0; i < filesToDownload.length; i++) {
String filename = filesToDownload[i];
DownloadEntry entry = entriesToDownload.get(filename);
if (entry != null) {
String indexOfAllFiles = filesToDownload.length <= 1 ? "" : (" [" + (i + 1) + "/"
+ filesToDownload.length + "]");
boolean result = downloadFileHelper.downloadFile(filename,
entry.fileToSave, entry.fileToUnzip, entry.unzip, progress, entry.dateModified,
entry.parts, filesToReindex, indexOfAllFiles, this);
if (result) {
entriesToDownload.remove(filename);
publishProgress(entry);
}
}
}
boolean vectorMapsToReindex = false;
for (File f : filesToReindex) {
if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
vectorMapsToReindex = true;
break;
}
}
// reindex vector maps all at one time
if (vectorMapsToReindex) {
ResourceManager manager = ((OsmandApplication) getApplication()).getResourceManager();
List<String> warnings = manager.indexingMaps(progress);
if (warnings.isEmpty() && !OsmandSettings.getOsmandSettings(getApplicationContext()).MAP_VECTOR_DATA.get()) {
warnings.add(getString(R.string.binary_map_download_success));
// Is it proper way to switch every tome to vector data?
OsmandSettings.getOsmandSettings(getApplicationContext()).MAP_VECTOR_DATA.set(true);
}
if (!warnings.isEmpty()) {
return warnings.get(0);
}
}
} catch (InterruptedException e) {
// do not dismiss dialog
progressFileDlg = null;
} finally {
if (progressFileDlg != null) {
progressFileDlg.dismiss();
progressFileDlg = null;
}
}
return null;
}
@Override
public void showWarning(String warning) {
publishProgress(warning);
}
}
private static class DownloadEntry {
public File fileToSave;
public File fileToUnzip;
public boolean unzip;
public Long dateModified;
public double sizeMB;
public String baseName;
public int parts;
}
protected class DownloadIndexAdapter extends ArrayAdapter<IndexItem> implements Filterable { protected class DownloadIndexAdapter extends ArrayAdapter<IndexItem> implements Filterable {

View file

@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -61,6 +62,7 @@ public class LocalIndexHelper {
updateObfFileInformation(info, f); updateObfFileInformation(info, f);
info.setDescription(info.getDescription() + getInstalledDate(f)); info.setDescription(info.getDescription() + getInstalledDate(f));
} else if(info.getType() == LocalIndexType.POI_DATA){ } else if(info.getType() == LocalIndexType.POI_DATA){
checkPoiFileVersion(info, f);
info.setDescription(getInstalledDate(f)); info.setDescription(getInstalledDate(f));
} else if(info.getType() == LocalIndexType.GPX_DATA){ } else if(info.getType() == LocalIndexType.GPX_DATA){
updateGpxInfo(info, f); updateGpxInfo(info, f);
@ -210,7 +212,7 @@ public class LocalIndexHelper {
private void loadVoiceData(File voiceDir, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) { private void loadVoiceData(File voiceDir, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) {
if (voiceDir.canRead()) { if (voiceDir.canRead()) {
for (File voiceF : voiceDir.listFiles()) { for (File voiceF : listFilesSorted(voiceDir)) {
if (voiceF.isDirectory()) { if (voiceF.isDirectory()) {
LocalIndexInfo info = null; LocalIndexInfo info = null;
if (MediaCommandPlayerImpl.isMyData(voiceF)) { if (MediaCommandPlayerImpl.isMyData(voiceF)) {
@ -231,7 +233,7 @@ public class LocalIndexHelper {
private void loadTilesData(File tilesPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) { private void loadTilesData(File tilesPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) {
if (tilesPath.canRead()) { if (tilesPath.canRead()) {
for (File tileFile : tilesPath.listFiles()) { for (File tileFile : listFilesSorted(tilesPath)) {
if (tileFile.isFile() && tileFile.getName().endsWith(SQLiteTileSource.EXT)) { if (tileFile.isFile() && tileFile.getName().endsWith(SQLiteTileSource.EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.TILES_DATA, tileFile, backup); LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.TILES_DATA, tileFile, backup);
result.add(info); result.add(info);
@ -253,7 +255,7 @@ public class LocalIndexHelper {
private void loadObfData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask, Map<String, String> loadedMaps) { private void loadObfData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask, Map<String, String> loadedMaps) {
if (mapPath.canRead()) { if (mapPath.canRead()) {
for (File mapFile : mapPath.listFiles()) { for (File mapFile : listFilesSorted(mapPath)) {
if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.MAP_DATA, mapFile, backup); LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.MAP_DATA, mapFile, backup);
if(loadedMaps.containsKey(mapFile.getName()) && !backup){ if(loadedMaps.containsKey(mapFile.getName()) && !backup){
@ -268,7 +270,7 @@ public class LocalIndexHelper {
private void loadGPXData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) { private void loadGPXData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) {
if (mapPath.canRead()) { if (mapPath.canRead()) {
for (File gpxFile : mapPath.listFiles()) { for (File gpxFile : listFilesSorted(mapPath)) {
if (gpxFile.isFile() && gpxFile.getName().endsWith(".gpx")) { if (gpxFile.isFile() && gpxFile.getName().endsWith(".gpx")) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.GPX_DATA, gpxFile, backup); LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.GPX_DATA, gpxFile, backup);
result.add(info); result.add(info);
@ -278,9 +280,15 @@ public class LocalIndexHelper {
} }
} }
private File[] listFilesSorted(File dir){
File[] listFiles = dir.listFiles();
Arrays.sort(listFiles);
return listFiles;
}
private void loadPoiData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) { private void loadPoiData(File mapPath, List<LocalIndexInfo> result, boolean backup, LoadLocalIndexTask loadTask) {
if (mapPath.canRead()) { if (mapPath.canRead()) {
for (File poiFile : mapPath.listFiles()) { for (File poiFile : listFilesSorted(mapPath)) {
if (poiFile.isFile() && poiFile.getName().endsWith(IndexConstants.POI_INDEX_EXT)) { if (poiFile.isFile() && poiFile.getName().endsWith(IndexConstants.POI_INDEX_EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.POI_DATA, poiFile, backup); LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.POI_DATA, poiFile, backup);
if (!backup) { if (!backup) {

View file

@ -6,11 +6,11 @@ import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import net.osmand.Algoritms; import net.osmand.Algoritms;
import net.osmand.FavouritePoint;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -35,7 +35,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.BaseExpandableListAdapter; import android.widget.BaseExpandableListAdapter;
@ -44,12 +43,11 @@ import android.widget.CheckBox;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo; import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
public class LocalIndexesActivity extends ExpandableListActivity { public class LocalIndexesActivity extends ExpandableListActivity {
private AsyncTask<Activity, LocalIndexInfo, List<LocalIndexInfo>> asyncLoader; private LoadLocalIndexTask asyncLoader;
private LocalIndexesAdapter listAdapter; private LocalIndexesAdapter listAdapter;
private LoadLocalIndexDescriptionTask descriptionLoader; private LoadLocalIndexDescriptionTask descriptionLoader;
private LocalIndexOperationTask operationTask; private LocalIndexOperationTask operationTask;
@ -61,17 +59,23 @@ public class LocalIndexesActivity extends ExpandableListActivity {
protected static int BACKUP_OPERATION = 2; protected static int BACKUP_OPERATION = 2;
protected static int RESTORE_OPERATION = 3; protected static int RESTORE_OPERATION = 3;
@SuppressWarnings("unchecked")
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE); // requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.local_index); setContentView(R.layout.local_index);
LoadLocalIndexTask task = new LoadLocalIndexTask();
asyncLoader = task.execute(this);
descriptionLoader = new LoadLocalIndexDescriptionTask(); descriptionLoader = new LoadLocalIndexDescriptionTask();
listAdapter = new LocalIndexesAdapter(); listAdapter = new LocalIndexesAdapter();
Object indexes = getLastNonConfigurationInstance();
asyncLoader = new LoadLocalIndexTask();
if(indexes instanceof List<?>){
asyncLoader.setResult((List<LocalIndexInfo>) indexes);
} else {
asyncLoader.execute(this);
}
findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener() { findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -84,16 +88,19 @@ public class LocalIndexesActivity extends ExpandableListActivity {
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
long packedPos = ((ExpandableListContextMenuInfo)menuInfo).packedPosition; long packedPos = ((ExpandableListContextMenuInfo)menuInfo).packedPosition;
int group = ExpandableListView.getPackedPositionGroup(packedPos);
final LocalIndexInfo point = (LocalIndexInfo) listAdapter.getChild(ExpandableListView.getPackedPositionGroup(packedPos), int child = ExpandableListView.getPackedPositionChild(packedPos);
ExpandableListView.getPackedPositionChild(packedPos)); if (child >= 0 && group >= 0) {
if(point.getGpxFile() != null){ final LocalIndexInfo point = (LocalIndexInfo) listAdapter.getChild(group, child);
Location loc = point.getGpxFile().findFistLocation(); if (point != null && point.getGpxFile() != null) {
if(loc != null){ Location loc = point.getGpxFile().findFistLocation();
OsmandSettings.getOsmandSettings(LocalIndexesActivity.this).setMapLocationToShow(loc.getLatitude(),loc.getLongitude()); if (loc != null) {
OsmandSettings.getOsmandSettings(LocalIndexesActivity.this).setMapLocationToShow(loc.getLatitude(),
loc.getLongitude());
}
((OsmandApplication) getApplication()).setGpxFileToDisplay(point.getGpxFile());
MapActivity.launchMapActivityMoveToTop(LocalIndexesActivity.this);
} }
((OsmandApplication) getApplication()).setGpxFileToDisplay(point.getGpxFile());
MapActivity.launchMapActivityMoveToTop(LocalIndexesActivity.this);
} }
} }
}); });
@ -102,12 +109,12 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
public class LoadLocalIndexTask extends AsyncTask<Activity, LocalIndexInfo, List<LocalIndexInfo>> { public class LoadLocalIndexTask extends AsyncTask<Activity, LocalIndexInfo, List<LocalIndexInfo>> {
List<LocalIndexInfo> progress = new ArrayList<LocalIndexInfo>();
private List<LocalIndexInfo> result;
@Override @Override
protected List<LocalIndexInfo> doInBackground(Activity... params) { protected List<LocalIndexInfo> doInBackground(Activity... params) {
LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) getApplication()); LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) getApplication());
progress.clear();
return helper.getAllLocalIndexData(this); return helper.getAllLocalIndexData(this);
} }
@ -127,11 +134,25 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
public void setResult(List<LocalIndexInfo> result) {
this.result = result;
for (LocalIndexInfo v : result) {
listAdapter.addLocalIndexInfo(v);
}
listAdapter.notifyDataSetChanged();
onPostExecute(result);
}
@Override @Override
protected void onPostExecute(List<LocalIndexInfo> result) { protected void onPostExecute(List<LocalIndexInfo> result) {
this.result = result;
findViewById(R.id.ProgressBar).setVisibility(View.GONE); findViewById(R.id.ProgressBar).setVisibility(View.GONE);
} }
public List<LocalIndexInfo> getResult() {
return result;
}
} }
@ -240,7 +261,11 @@ public class LocalIndexesActivity extends ExpandableListActivity {
protected void onPostExecute(String result) { protected void onPostExecute(String result) {
findViewById(R.id.ProgressBar).setVisibility(View.GONE); findViewById(R.id.ProgressBar).setVisibility(View.GONE);
Toast.makeText(LocalIndexesActivity.this, result, Toast.LENGTH_LONG).show(); Toast.makeText(LocalIndexesActivity.this, result, Toast.LENGTH_LONG).show();
listAdapter.clear();
asyncLoader = new LoadLocalIndexTask();
asyncLoader.execute(LocalIndexesActivity.this);
reloadIndexes(); reloadIndexes();
} }
} }
@ -303,7 +328,13 @@ public class LocalIndexesActivity extends ExpandableListActivity {
descriptionLoader.cancel(true); descriptionLoader.cancel(true);
} }
@Override
public Object onRetainNonConfigurationInstance() {
if(asyncLoader != null){
return asyncLoader.getResult();
}
return super.onRetainNonConfigurationInstance();
}
@Override @Override
@ -341,6 +372,13 @@ public class LocalIndexesActivity extends ExpandableListActivity {
closeSelectionMode(); closeSelectionMode();
} }
private void collapseAllGroups() {
for (int i = 0; i < listAdapter.getGroupCount(); i++) {
getExpandableListView().collapseGroup(i);
}
}
private void openSelectionMode(final int actionResId){ private void openSelectionMode(final int actionResId){
final String actionButton = getString(actionResId); final String actionButton = getString(actionResId);
if(listAdapter.getGroupCount() == 0){ if(listAdapter.getGroupCount() == 0){
@ -348,8 +386,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
Toast.makeText(LocalIndexesActivity.this, getString(R.string.local_index_no_items_to_do, actionButton.toLowerCase()), Toast.LENGTH_SHORT).show(); Toast.makeText(LocalIndexesActivity.this, getString(R.string.local_index_no_items_to_do, actionButton.toLowerCase()), Toast.LENGTH_SHORT).show();
return; return;
} }
collapseAllGroups();
selectionMode = true; selectionMode = true;
selectedItems.clear(); selectedItems.clear();
Button action = (Button) findViewById(R.id.ActionButton); Button action = (Button) findViewById(R.id.ActionButton);
@ -403,6 +440,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
findViewById(R.id.CancelButton).setVisibility(View.GONE); findViewById(R.id.CancelButton).setVisibility(View.GONE);
findViewById(R.id.ActionButton).setVisibility(View.GONE); findViewById(R.id.ActionButton).setVisibility(View.GONE);
listAdapter.cancelFilter(); listAdapter.cancelFilter();
collapseAllGroups();
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
@ -472,9 +510,16 @@ public class LocalIndexesActivity extends ExpandableListActivity {
private MessageFormat formatMb; private MessageFormat formatMb;
public LocalIndexesAdapter() { public LocalIndexesAdapter() {
formatMb = new MessageFormat("{0, number,##.#} MB"); formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
} }
public void clear() {
data.clear();
category.clear();
filterCategory = null;
notifyDataSetChanged();
}
public LocalIndexInfo findCategory(LocalIndexInfo val, boolean backuped){ public LocalIndexInfo findCategory(LocalIndexInfo val, boolean backuped){
for(LocalIndexInfo i : category){ for(LocalIndexInfo i : category){
if(i.isBackupedData() == backuped && val.getType() == i.getType() ){ if(i.isBackupedData() == backuped && val.getType() == i.getType() ){
@ -642,10 +687,32 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
StringBuilder t = new StringBuilder(group.getType().getHumanString(LocalIndexesActivity.this)); StringBuilder t = new StringBuilder(group.getType().getHumanString(LocalIndexesActivity.this));
if (group.isBackupedData()) { if (group.isBackupedData()) {
t.append("* "); t.append(" - ").append(getString(R.string.local_indexes_cat_backup));
} }
TextView nameView = ((TextView) v.findViewById(R.id.local_index_category_name)); TextView nameView = ((TextView) v.findViewById(R.id.local_index_category_name));
t.append(" [").append(getChildrenCount(groupPosition)).append(" ").append(getString(R.string.local_index_items)).append("]"); t.append(" [").append(getChildrenCount(groupPosition));
if(getString(R.string.local_index_items).length() > 0){
t.append(" ").append(getString(R.string.local_index_items));
}
if(getString(R.string.local_index_items).length() > 0){
t.append(" ").append(getString(R.string.local_index_items));
}
List<LocalIndexInfo> list = data.get(group);
int size = 0;
for(int i=0; i<list.size(); i++){
int sz = list.get(i).getSize();
if(sz < 0){
size = 0;
break;
} else {
size += sz;
}
}
size = size / (1 << 10);
if(size > 0){
t.append(", ").append(size).append(" MB");
}
t.append("]");
nameView.setText(t.toString()); nameView.setText(t.toString());
if (!group.isBackupedData()) { if (!group.isBackupedData()) {
nameView.setTypeface(Typeface.DEFAULT, Typeface.NORMAL); nameView.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);

View file

@ -35,6 +35,7 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Handler; import android.os.Handler;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.util.Log; import android.util.Log;

View file

@ -6,7 +6,6 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -23,7 +22,6 @@ import net.osmand.osm.MapUtils;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.RoutingHelper.RouteDirectionInfo; import net.osmand.plus.activities.RoutingHelper.RouteDirectionInfo;
import net.osmand.plus.activities.RoutingHelper.TurnType; import net.osmand.plus.activities.RoutingHelper.TurnType;
import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.router.BicycleRouter; import net.osmand.router.BicycleRouter;
import net.osmand.router.BinaryRoutePlanner; import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.CarRouter; import net.osmand.router.CarRouter;
@ -180,35 +178,7 @@ public class RouteProvider {
try { try {
RouteCalculationResult res; RouteCalculationResult res;
if(gpxRoute != null && !gpxRoute.isEmpty()){ if(gpxRoute != null && !gpxRoute.isEmpty()){
// get the closest point to start and to end res = calculateGpxRoute(start, end, gpxRoute);
float minDist = Integer.MAX_VALUE;
int startI = 0;
int endI = gpxRoute.size();
if (start != null) {
for (int i = 0; i < gpxRoute.size(); i++) {
float d = gpxRoute.get(i).distanceTo(start);
if (d < minDist) {
startI = i;
minDist = d;
}
}
} else {
start = gpxRoute.get(0);
}
Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(end.getLatitude());
l.setLongitude(end.getLongitude());
minDist = Integer.MAX_VALUE;
// get in reverse order taking into account cycle ways
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
float d = gpxRoute.get(i).distanceTo(l);
if (d < minDist) {
endI = i + 1;
// slightly modify to allow last point to be added
minDist = d - 40;
}
}
res = new RouteCalculationResult(new ArrayList<Location>(gpxRoute.subList(startI, endI)), null, start, end, null);
addMissingTurnsToRoute(res, start, end, mode, ctx); addMissingTurnsToRoute(res, start, end, mode, ctx);
} else if (type == RouteService.YOURS) { } else if (type == RouteService.YOURS) {
res = findYOURSRoute(start, end, mode, fast); res = findYOURSRoute(start, end, mode, fast);
@ -235,6 +205,40 @@ public class RouteProvider {
} }
return new RouteCalculationResult(null); return new RouteCalculationResult(null);
} }
private RouteCalculationResult calculateGpxRoute(Location start, LatLon end, List<Location> gpxRoute) {
RouteCalculationResult res;
// get the closest point to start and to end
float minDist = Integer.MAX_VALUE;
int startI = 0;
int endI = gpxRoute.size();
if (start != null) {
for (int i = 0; i < gpxRoute.size(); i++) {
float d = gpxRoute.get(i).distanceTo(start);
if (d < minDist) {
startI = i;
minDist = d;
}
}
} else {
start = gpxRoute.get(0);
}
Location l = new Location("temp"); //$NON-NLS-1$
l.setLatitude(end.getLatitude());
l.setLongitude(end.getLongitude());
minDist = Integer.MAX_VALUE;
// get in reverse order taking into account cycle ways
for (int i = gpxRoute.size() - 1; i >= startI; i--) {
float d = gpxRoute.get(i).distanceTo(l);
if (d < minDist) {
endI = i + 1;
// slightly modify to allow last point to be added
minDist = d - 40;
}
}
res = new RouteCalculationResult(new ArrayList<Location>(gpxRoute.subList(startI, endI)), null, start, end, null);
return res;
}
protected String getString(Context ctx, int resId){ protected String getString(Context ctx, int resId){
if(ctx == null){ if(ctx == null){
@ -579,7 +583,7 @@ public class RouteProvider {
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder(); DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dom.parse(new InputSource(new InputStreamReader(connection.getInputStream()))); Document doc = dom.parse(new InputSource(new InputStreamReader(connection.getInputStream())));
// TODO how to find that error occurred ? API gpx doesn't say nothing // TODO how to find that error occurred ? Gpx API doesn't say anything
NodeList list = doc.getElementsByTagName("wpt"); //$NON-NLS-1$ NodeList list = doc.getElementsByTagName("wpt"); //$NON-NLS-1$
for (int i = 0; i < list.getLength(); i++) { for (int i = 0; i < list.getLength(); i++) {
Element item = (Element) list.item(i); Element item = (Element) list.item(i);