Added gpx database

This commit is contained in:
Alexey Kulish 2017-02-19 12:18:07 +03:00
parent ac6e20f2e5
commit 80cd4b4c4f
5 changed files with 228 additions and 81 deletions

View file

@ -360,6 +360,7 @@ public class AppInitializer implements IProgress {
app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class);
app.liveMonitoringHelper = startupInit(new LiveMonitoringHelper(app), LiveMonitoringHelper.class);
app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.class);
app.gpxDatabase = startupInit(new GPXDatabase(app), GPXDatabase.class);
app.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class);
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);

View file

@ -2,7 +2,8 @@ package net.osmand.plus;
import net.osmand.IndexConstants;
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
import net.osmand.plus.api.SQLiteAPI;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.util.Algorithms;
import java.io.File;
@ -59,6 +60,14 @@ public class GPXDatabase {
GPX_COL_POINTS + " int, " +
GPX_COL_WPT_POINTS + " int);";
private static final String GPX_TABLE_SELECT = "SELECT " + GPX_COL_NAME + ", " + GPX_COL_DIR + "," + GPX_COL_TOTAL_DISTANCE + ", " +
GPX_COL_TOTAL_TRACKS + ", " + GPX_COL_START_TIME + ", " + GPX_COL_END_TIME + ", " +
GPX_COL_TIME_SPAN + ", " + GPX_COL_TIME_MOVING + ", " + GPX_COL_TOTAL_DISTANCE_MOVING + ", " +
GPX_COL_DIFF_ELEVATION_UP + ", " + GPX_COL_DIFF_ELEVATION_DOWN + ", " + GPX_COL_AVG_ELEVATION + ", " +
GPX_COL_MIN_ELEVATION + ", " + GPX_COL_MAX_ELEVATION + ", " + GPX_COL_MAX_SPEED + ", " +
GPX_COL_AVG_SPEED + ", " + GPX_COL_POINTS + ", " + GPX_COL_WPT_POINTS +
" FROM " + GPX_TABLE_NAME;
private OsmandApplication context;
public static class GpxDataItem {
@ -83,8 +92,8 @@ public class GPXDatabase {
context = app;
}
private SQLiteAPI.SQLiteConnection openConnection(boolean readonly) {
SQLiteAPI.SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
private SQLiteConnection openConnection(boolean readonly) {
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
if (conn.getVersion() == 0 || DB_VERSION != conn.getVersion()) {
if (readonly) {
conn.close();
@ -101,11 +110,11 @@ public class GPXDatabase {
return conn;
}
public void onCreate(SQLiteAPI.SQLiteConnection db) {
public void onCreate(SQLiteConnection db) {
db.execSQL(GPX_TABLE_CREATE);
}
public void onUpgrade(SQLiteAPI.SQLiteConnection db, int oldVersion, int newVersion) {
public void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
/*
if (newVersion == 2) {
db.execSQL(GPX_TABLE_CREATE);
@ -114,12 +123,19 @@ public class GPXDatabase {
*/
}
public boolean remove(GpxDataItem item) {
SQLiteAPI.SQLiteConnection db = openConnection(false);
public boolean rename(File currentFile, File newFile) {
SQLiteConnection db = openConnection(false);
if(db != null){
try {
db.execSQL("DELETE FROM " + GPX_TABLE_NAME + " WHERE " + GPX_COL_NAME + " = ?, " + GPX_COL_DIR + " = ?",
new Object[] { item.file.getName(), item.file.getParentFile().getName() });
String newFileName = getFileName(newFile);
String newFileDir = getFileDir(newFile);
String fileName = getFileName(currentFile);
String fileDir = getFileDir(currentFile);
db.execSQL("UPDATE " + GPX_TABLE_NAME + " SET " +
GPX_COL_NAME + " = ? " + ", " +
GPX_COL_DIR + " = ? " +
" WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
new Object[] { newFileName, newFileDir, fileName, fileDir });
} finally {
db.close();
}
@ -128,8 +144,28 @@ public class GPXDatabase {
return false;
}
public boolean remove(File file) {
SQLiteConnection db = openConnection(false);
if(db != null){
try {
String fileName = getFileName(file);
String fileDir = getFileDir(file);
db.execSQL("DELETE FROM " + GPX_TABLE_NAME + " WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
new Object[] { fileName, fileDir });
} finally {
db.close();
}
return true;
}
return false;
}
public boolean remove(GpxDataItem item) {
return remove(item.file);
}
public boolean add(GpxDataItem item) {
SQLiteAPI.SQLiteConnection db = openConnection(false);
SQLiteConnection db = openConnection(false);
if(db != null){
try {
insert(item, db);
@ -141,9 +177,18 @@ public class GPXDatabase {
return false;
}
private void insert(GpxDataItem item, SQLiteAPI.SQLiteConnection db) {
String fileName = item.file.getName();
String fileDir = item.file.getParentFile().getName();
private String getFileName(File itemFile) {
return itemFile.getName();
}
private String getFileDir(File itemFile) {
return itemFile.getParentFile().equals(context.getAppPath(IndexConstants.GPX_INDEX_DIR)) ?
"" : itemFile.getParentFile().getName();
}
private void insert(GpxDataItem item, SQLiteConnection db) {
String fileName = getFileName(item.file);
String fileDir = getFileDir(item.file);
GPXTrackAnalysis a = item.getAnalysis();
db.execSQL(
"INSERT INTO " + GPX_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
@ -152,69 +197,63 @@ public class GPXDatabase {
a.avgElevation, a.minElevation, a.maxElevation, a.maxSpeed, a.avgSpeed, a.points, a.wptPoints });
}
private GpxDataItem readItem(SQLiteCursor query) {
String fileName = query.getString(0);
String fileDir = query.getString(1);
float totalDistance = (float)query.getDouble(2);
int totalTracks = (int)query.getInt(3);
long startTime = query.getLong(4);
long endTime = query.getLong(5);
long timeSpan = query.getLong(6);
long timeMoving = query.getLong(7);
float totalDistanceMoving = (float)query.getDouble(8);
double diffElevationUp = query.getDouble(9);
double diffElevationDown = query.getDouble(10);
double avgElevation = query.getDouble(11);
double minElevation = query.getDouble(12);
double maxElevation = query.getDouble(13);
float maxSpeed = (float)query.getDouble(14);
float avgSpeed = (float)query.getDouble(15);
int points = (int)query.getInt(16);
int wptPoints = (int)query.getInt(17);
GPXTrackAnalysis a = new GPXTrackAnalysis();
a.totalDistance = totalDistance;
a.totalTracks = totalTracks;
a.startTime = startTime;
a.endTime = endTime;
a.timeSpan = timeSpan;
a.timeMoving = timeMoving;
a.totalDistanceMoving = totalDistanceMoving;
a.diffElevationUp = diffElevationUp;
a.diffElevationDown = diffElevationDown;
a.avgElevation = avgElevation;
a.minElevation = minElevation;
a.maxElevation = maxElevation;
a.maxSpeed = maxSpeed;
a.avgSpeed = avgSpeed;
a.points = points;
a.wptPoints = wptPoints;
File dir;
if (!Algorithms.isEmpty(fileDir)) {
dir = new File(context.getAppPath(IndexConstants.GPX_INDEX_DIR), fileDir);
} else {
dir = context.getAppPath(IndexConstants.GPX_INDEX_DIR);
}
return new GpxDataItem(new File(dir, fileName), a);
}
public List<GpxDataItem> getItems() {
List<GpxDataItem> items = new ArrayList<>();
SQLiteAPI.SQLiteConnection db = openConnection(true);
if(db != null){
SQLiteConnection db = openConnection(true);
if (db != null){
try {
SQLiteAPI.SQLiteCursor query = db.rawQuery(
"SELECT " + GPX_COL_NAME + ", " + GPX_COL_DIR + "," + GPX_COL_TOTAL_DISTANCE + ", " +
GPX_COL_TOTAL_TRACKS + ", " + GPX_COL_START_TIME + ", " + GPX_COL_END_TIME + ", " +
GPX_COL_TIME_SPAN + ", " + GPX_COL_TIME_MOVING + ", " + GPX_COL_TOTAL_DISTANCE_MOVING + ", " +
GPX_COL_DIFF_ELEVATION_UP + ", " + GPX_COL_DIFF_ELEVATION_DOWN + ", " + GPX_COL_AVG_ELEVATION + ", " +
GPX_COL_MIN_ELEVATION + ", " + GPX_COL_MAX_ELEVATION + ", " + GPX_COL_MAX_SPEED + ", " +
GPX_COL_AVG_SPEED + ", " + GPX_COL_POINTS + ", " + GPX_COL_WPT_POINTS +
" FROM " + GPX_TABLE_NAME , null);
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT , null);
if (query.moveToFirst()) {
do {
String fileName = query.getString(0);
String fileDir = query.getString(1);
float totalDistance = (float)query.getDouble(2);
int totalTracks = (int)query.getInt(3);
long startTime = query.getLong(4);
long endTime = query.getLong(5);
long timeSpan = query.getLong(6);
long timeMoving = query.getLong(7);
float totalDistanceMoving = (float)query.getDouble(8);
double diffElevationUp = query.getDouble(9);
double diffElevationDown = query.getDouble(10);
double avgElevation = query.getDouble(11);
double minElevation = query.getDouble(12);
double maxElevation = query.getDouble(13);
float maxSpeed = (float)query.getDouble(14);
float avgSpeed = (float)query.getDouble(15);
int points = (int)query.getInt(16);
int wptPoints = (int)query.getInt(17);
GPXTrackAnalysis a = new GPXTrackAnalysis();
a.totalDistance = totalDistance;
a.totalTracks = totalTracks;
a.startTime = startTime;
a.endTime = endTime;
a.timeSpan = timeSpan;
a.timeMoving = timeMoving;
a.totalDistanceMoving = totalDistanceMoving;
a.diffElevationUp = diffElevationUp;
a.diffElevationDown = diffElevationDown;
a.avgElevation = avgElevation;
a.minElevation = minElevation;
a.maxElevation = maxElevation;
a.maxSpeed = maxSpeed;
a.avgSpeed = avgSpeed;
a.points = points;
a.wptPoints = wptPoints;
File dir;
if (!Algorithms.isEmpty(fileDir)) {
dir = new File(context.getAppPath(IndexConstants.GPX_INDEX_DIR), fileDir);
} else {
dir = context.getAppPath(IndexConstants.GPX_INDEX_DIR);
}
GpxDataItem item = new GpxDataItem(new File(dir, fileName), a);
items.add(item);
items.add(readItem(query));
} while (query.moveToNext());
}
query.close();
} finally {
@ -223,4 +262,24 @@ public class GPXDatabase {
}
return items;
}
public GpxDataItem getItem(File file) {
GpxDataItem result = null;
SQLiteConnection db = openConnection(true);
if (db != null){
try {
String fileName = getFileName(file);
String fileDir = getFileDir(file);
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT + " WHERE " + GPX_COL_NAME + " = ? AND " +
GPX_COL_DIR + " = ?", new String[] { fileName, fileDir });
if (query.moveToFirst()) {
result = readItem(query);
}
query.close();
} finally {
db.close();
}
}
return result;
}
}

View file

@ -95,6 +95,7 @@ public class OsmandApplication extends MultiDexApplication {
FavouritesDbHelper favorites;
CommandPlayer player;
GpxSelectionHelper selectedGpxHelper;
GPXDatabase gpxDatabase;
SavingTrackHelper savingTrackHelper;
NotificationHelper notificationHelper;
LiveMonitoringHelper liveMonitoringHelper;
@ -272,6 +273,10 @@ public class OsmandApplication extends MultiDexApplication {
return selectedGpxHelper;
}
public GPXDatabase getGpxDatabase() {
return gpxDatabase;
}
public FavouritesDbHelper getFavorites() {
return favorites;
}

View file

@ -213,10 +213,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
private boolean performBasicOperation(int resId, final LocalIndexInfo info) {
if (resId == R.string.shared_string_rename) {
renameFile(getActivity(), new File(info.getPathToData()), new Runnable() {
renameFile(getActivity(), new File(info.getPathToData()), new RenameCallback() {
@Override
public void run() {
public void renamedTo(File file) {
getDownloadActivity().reloadLocalIndexes();
}
});
@ -256,7 +256,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
return true;
}
public static void renameFile(final Activity a, final File f, final Runnable callback) {
public static void renameFile(final Activity a, final File f, final RenameCallback callback) {
AlertDialog.Builder b = new AlertDialog.Builder(a);
if (f.exists()) {
int xt = f.getName().lastIndexOf('.');
@ -312,7 +312,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
}
if (f.renameTo(dest)) {
if (callback != null) {
callback.run();
callback.renamedTo(dest);
}
} else {
Toast.makeText(a, R.string.file_can_not_be_renamed,
@ -1234,10 +1234,12 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
optionsMenu.show();
}
private DownloadActivity getDownloadActivity() {
return (DownloadActivity) getActivity();
}
public interface RenameCallback {
public void renamedTo(File file);
}
}

View file

@ -38,6 +38,7 @@ import net.osmand.IndexConstants;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
@ -58,6 +59,7 @@ import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.OsmandExpandableListFragment;
import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.download.ui.LocalIndexesFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment.RenameCallback;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.osmedit.OsmEditingPlugin;
@ -86,6 +88,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
private List<GpxInfo> selectedItems = new ArrayList<>();
private ActionMode actionMode;
private LoadGpxTask asyncLoader;
private ProcessGpxTask asyncProcessor;
private GpxIndexesAdapter allGpxAdapter;
private static MessageFormat formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
private ContextMenuAdapter optionsMenuAdapter;
@ -141,6 +144,8 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
allGpxAdapter.refreshSelected();
allGpxAdapter.notifyDataSetChanged();
}
asyncProcessor = new ProcessGpxTask();
asyncProcessor.execute();
updateCurrentTrack();
updateEnable = true;
@ -154,6 +159,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
if (operationTask != null) {
operationTask.cancel(true);
}
if (asyncProcessor != null) {
asyncProcessor.cancel(false);
asyncProcessor = null;
}
}
public void updateCurrentTrack() {
@ -354,6 +363,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
if (itemId == R.string.local_index_mi_reload) {
asyncLoader = new LoadGpxTask();
asyncLoader.execute(getActivity());
if (asyncProcessor == null) {
asyncProcessor = new ProcessGpxTask();
asyncProcessor.execute();
}
} else if (itemId == R.string.shared_string_show_on_map) {
openShowOnMapMode();
} else if (itemId == R.string.shared_string_delete) {
@ -623,6 +636,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
} else {
if (info.file.renameTo(dest)) {
app.getGpxDatabase().rename(info.file, dest);
asyncLoader = new LoadGpxTask();
asyncLoader.execute(getActivity());
} else {
@ -1086,10 +1100,10 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new Runnable() {
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new RenameCallback() {
@Override
public void run() {
public void renamedTo(File file) {
app.getGpxDatabase().rename(gpxInfo.file, file);
asyncLoader = new LoadGpxTask();
asyncLoader.execute(getActivity());
}
@ -1157,6 +1171,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
if (!isCancelled() && (info.gpx == null || !info.gpx.showCurrentTrack)) {
boolean successfull;
successfull = Algorithms.removeAllFiles(info.file);
app.getGpxDatabase().remove(info.file);
total++;
if (successfull) {
count++;
@ -1239,6 +1254,67 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
}
}
public class ProcessGpxTask extends AsyncTask<Void, GpxDataItem, Void> {
private List<File> processedDataFiles = new ArrayList<>();
ProcessGpxTask() {
List<GpxDataItem> dataItems = app.getGpxDatabase().getItems();
for (GpxDataItem item : dataItems) {
processedDataFiles.add(item.getFile());
}
}
@Override
protected Void doInBackground(Void... params) {
File gpxPath = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
if (gpxPath.canRead()) {
processGPXFolder(gpxPath, "");
}
return null;
}
private File[] listFilesSorted(File dir) {
File[] listFiles = dir.listFiles();
if (listFiles == null) {
return new File[0];
}
Arrays.sort(listFiles);
return listFiles;
}
private void processGPXFolder(File gpxPath, String gpxSubfolder) {
for (File gpxFile : listFilesSorted(gpxPath)) {
if (gpxFile.isDirectory()) {
String sub = gpxSubfolder.length() == 0 ?
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
processGPXFolder(gpxFile, sub);
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx") && !processedDataFiles.contains(gpxFile)) {
GPXFile f = GPXUtilities.loadGPXFile(app, gpxFile);
GPXTrackAnalysis analysis = f.getAnalysis(gpxFile.lastModified());
GpxDataItem newItem = new GpxDataItem(gpxFile, analysis);
app.getGpxDatabase().add(newItem);
if (isCancelled()) {
break;
}
processedDataFiles.add(gpxFile);
publishProgress(newItem);
}
}
}
@Override
protected void onProgressUpdate(GpxDataItem... items) {
allGpxAdapter.notifyDataSetChanged();
}
@Override
protected void onPostExecute(Void aVoid) {
asyncProcessor = null;
}
}
private class SearchFilter extends Filter {
@ -1421,7 +1497,11 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
if (sgpx != null) {
icon.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_action_polygom_dark, R.color.color_distance));
analysis = sgpx.getTrackAnalysis();
} else {
GpxDataItem dataItem = app.getGpxDatabase().getItem(child.file);
if (dataItem != null) {
analysis = dataItem.getAnalysis();
}
}
boolean sectionRead = analysis == null;
if (sectionRead) {