diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java index 1d5c48f..cf7d1b7 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java @@ -36,6 +36,8 @@ public class BRouterActivity extends Activity implements OnInitListener private static final int DIALOG_SELECTBASEDIR_ID = 11; private static final int DIALOG_MAINACTION_ID = 12; private static final int DIALOG_OLDDATAHINT_ID = 13; + private static final int DIALOG_SHOW_WP_HELP_ID = 14; + private static final int DIALOG_SHOW_WP_SCANRESULT_ID = 15; private BRouterView mBRouterView; private PowerManager mPowerManager; @@ -117,6 +119,51 @@ public class BRouterActivity extends Activity implements OnInitListener } } ); return builder.create(); + case DIALOG_SHOW_WP_HELP_ID: + builder = new AlertDialog.Builder( this ); + builder + .setTitle( "No Waypoint Database found" ) + .setMessage( + "The simple scan did not find any map-tool directory including a waypoint database. " + + "Reason could be there is no map-tool installed (osmand, locus or oruxmaps), or at an " + + "unusual path, or it contains no waypoints yet. That's o.k. if you want to use BRouter " + + "in server-mode only - in that case you can still use the 'Server-Mode' button to " + + "configure the profile mapping. But you will not be able to use nogo-points or do " + + "long distance calculations. If you know the path to your map-tool, you can manually " + + "configure it in 'storageconfig.txt'. Or I can do an extended scan searching " + + "your sd-card for a valid waypoint database" ).setPositiveButton( "Scan", new DialogInterface.OnClickListener() + { + public void onClick( DialogInterface dialog, int id ) + { + mBRouterView.startWpDatabaseScan(); + } + } ).setNegativeButton( "Exit", new DialogInterface.OnClickListener() + { + public void onClick( DialogInterface dialog, int id ) + { + finish(); + } + } ); + return builder.create(); + case DIALOG_SHOW_WP_SCANRESULT_ID: + builder = new AlertDialog.Builder( this ); + builder + .setTitle( "Waypoint Database " ) + .setMessage( "Found Waypoint-Database(s) for maptool-dir: " + maptoolDirCandidate + + " Configure that?" ).setPositiveButton( "Yes", new DialogInterface.OnClickListener() + { + public void onClick( DialogInterface dialog, int id ) + { + mBRouterView.saveMaptoolDir( maptoolDirCandidate ); + } + } ).setNegativeButton( "No", new DialogInterface.OnClickListener() + { + public void onClick( DialogInterface dialog, int id ) + { + finish(); + } + } ); + return builder.create(); case DIALOG_OLDDATAHINT_ID: builder = new AlertDialog.Builder( this ); builder @@ -257,17 +304,25 @@ public class BRouterActivity extends Activity implements OnInitListener } ); return builder.create(); case DIALOG_SHOWRESULT_ID: - String leftLabel = wpCount < 0 ? "Exit" : ( wpCount == 0 ? "Select from" : "Select to/via" ); + String leftLabel = wpCount < 0 ? ( wpCount == -1 ? "Exit" : "Help") : ( wpCount == 0 ? "Select from" : "Select to/via" ); String rightLabel = wpCount < 2 ? "Server-Mode" : "Calc Route"; builder = new AlertDialog.Builder( this ); builder.setTitle( title ).setMessage( errorMessage ).setPositiveButton( leftLabel, new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int id ) { - if ( wpCount < 0 ) + if ( wpCount == -2 ) + { + showWaypointDatabaseHelp(); + } + else if ( wpCount == -1 ) + { finish(); + } else + { mBRouterView.pickWaypoints(); + } } } ).setNegativeButton( rightLabel, new DialogInterface.OnClickListener() { @@ -338,6 +393,8 @@ public class BRouterActivity extends Activity implements OnInitListener private List nogoList; + private String maptoolDirCandidate; + public boolean isOnline() { ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE ); @@ -441,6 +498,19 @@ public class BRouterActivity extends Activity implements OnInitListener showNewDialog( DIALOG_PICKWAYPOINT_ID ); } + @SuppressWarnings("deprecation") + public void showWaypointDatabaseHelp() + { + showNewDialog( DIALOG_SHOW_WP_HELP_ID ); + } + + @SuppressWarnings("deprecation") + public void showWpDatabaseScanSuccess( String bestGuess ) + { + maptoolDirCandidate = bestGuess; + showNewDialog( DIALOG_SHOW_WP_SCANRESULT_ID ); + } + @SuppressWarnings("deprecation") public void selectNogos( List nogoList ) { diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java index 9b362cf..0b23feb 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java @@ -12,7 +12,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeMap; @@ -32,6 +31,7 @@ import android.widget.Toast; import btools.expressions.BExpressionContextGlobal; import btools.expressions.BExpressionMetaData; import btools.mapaccess.OsmNode; +import btools.mapaccess.StorageConfigHelper; import btools.router.OsmNodeNamed; import btools.router.OsmTrack; import btools.router.RoutingContext; @@ -66,6 +66,8 @@ public class BRouterView extends View private boolean needsNogoSelection; private boolean needsWaypointSelection; + private WpDatabaseScanner dataBaseScanner; + private long lastDataTime = System.currentTimeMillis(); private CoordinateReader cor; @@ -358,6 +360,19 @@ public class BRouterView extends View } } + public void startWpDatabaseScan() + { + dataBaseScanner = new WpDatabaseScanner(); + dataBaseScanner.start(); + invalidate(); + } + + public void saveMaptoolDir( String dir ) + { + ConfigMigration.saveAdditionalMaptoolDir( segmentDir, dir ); + ( (BRouterActivity) getContext() ).showResultMessage( "Success", "please restart to use new config", -1 ); + } + public void finishWaypointSelection() { needsWaypointSelection = false; @@ -390,7 +405,7 @@ public class BRouterView extends View String msg; if ( wpList.size() == 0 ) { - msg = "no from/to found\n" + sourceHint; + msg = "Expecting waypoint selection\n" + sourceHint; } else { @@ -398,7 +413,7 @@ public class BRouterView extends View for ( int i = 0; i < wpList.size(); i++ ) msg += ( i > 0 ? "->" : "" ) + wpList.get( i ).name; } - ( (BRouterActivity) getContext() ).showResultMessage( "Select Action", msg, wpList.size() ); + ( (BRouterActivity) getContext() ).showResultMessage( "Select Action", msg, cor instanceof CoordinateReaderNone ? -2 : wpList.size() ); return; } @@ -580,8 +595,59 @@ public class BRouterView extends View } } + private void showDatabaseScanning( Canvas canvas ) + { + try + { + Thread.sleep( 100 ); + } + catch (InterruptedException ie) + { + } + Paint paint1 = new Paint(); + paint1.setColor( Color.WHITE ); + paint1.setTextSize( 20 ); + + Paint paint2 = new Paint(); + paint2.setColor( Color.WHITE ); + paint2.setTextSize( 10 ); + + String currentDir = dataBaseScanner.getCurrentDir(); + String bestGuess = dataBaseScanner.getBestGuess(); + + if ( currentDir == null ) // scan finished + { + if ( bestGuess.length() == 0 ) + { + ( (BRouterActivity) getContext() ).showErrorMessage( "scan did not find any possible waypoint database" ); + } + else + { + ( (BRouterActivity) getContext() ).showWpDatabaseScanSuccess( bestGuess); + } + cr = null; + dataBaseScanner = null; + waitingForSelection = true; + return; + } + + canvas.drawText( "Scanning:", 10, 30, paint1 ); + canvas.drawText( currentDir, 0, 60, paint2 ); + canvas.drawText( "Best Guess:", 10, 90, paint1 ); + canvas.drawText( bestGuess, 0, 120, paint2 ); + canvas.drawText( "Last Error:", 10, 150, paint1 ); + canvas.drawText( dataBaseScanner.getLastError(), 0, 180, paint2 ); + + invalidate(); + } + private void _onDraw( Canvas canvas ) { + if ( dataBaseScanner != null ) + { + showDatabaseScanning( canvas ); + return; + } if ( waitingForSelection ) return; diff --git a/brouter-routing-app/src/main/java/btools/routingapp/ConfigMigration.java b/brouter-routing-app/src/main/java/btools/routingapp/ConfigMigration.java index 99e78a5..88645e1 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/ConfigMigration.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/ConfigMigration.java @@ -86,4 +86,61 @@ public class ConfigMigration } } } + + public static File saveAdditionalMaptoolDir( String segmentDir, String value ) + { + return saveStorageLocation( segmentDir, "additional_maptool_dir=", value ); + } + + private static File saveStorageLocation( String segmentDir, String tag, String value ) + { + File res = null; + BufferedReader br = null; + BufferedWriter bw = null; + String configFile = segmentDir + "/storageconfig.txt"; + List lines = new ArrayList(); + try + { + br = new BufferedReader( new FileReader( configFile ) ); + for ( ;; ) + { + String line = br.readLine(); + if ( line == null ) break; + if ( !line.trim().startsWith( tag ) ) + { + lines.add( line ); + } + } + lines.add( tag + value ); + br.close(); + br = null; + bw = new BufferedWriter( new FileWriter( configFile ) ); + for( String line : lines ) + { + bw.write( line + "\r\n" ); + } + } + catch (Exception e) { /* ignore */ } + finally + { + if ( br != null ) + { + try + { + br.close(); + } + catch (Exception ee) { /* ignore */ } + } + if ( bw != null ) + { + try + { + bw.close(); + } + catch (Exception ee) { /* ignore */ } + } + } + return res; + } + } diff --git a/brouter-routing-app/src/main/java/btools/routingapp/WpDatabaseScanner.java b/brouter-routing-app/src/main/java/btools/routingapp/WpDatabaseScanner.java new file mode 100644 index 0000000..cde4689 --- /dev/null +++ b/brouter-routing-app/src/main/java/btools/routingapp/WpDatabaseScanner.java @@ -0,0 +1,138 @@ +package btools.routingapp; + +import java.io.File; + +public class WpDatabaseScanner extends Thread +{ + private String currentDir = ""; + private String bestGuess = ""; + private String lastError = ""; + + private Object currentDirSync = new Object(); + + private long maxtimestamp = 0; + + public String getCurrentDir() + { + synchronized (currentDirSync) + { + return currentDir; + } + } + + private void setCurrentDir( String dir ) + { + synchronized (currentDirSync) + { + currentDir = dir; + } + } + + public String getBestGuess() + { + synchronized (currentDirSync) + { + return bestGuess; + } + } + + public String getLastError() + { + synchronized (currentDirSync) + { + return lastError; + } + } + + private void setLastError( String msg ) + { + synchronized (currentDirSync) + { + lastError = msg; + } + } + + private static String[] vetos = new String[] { "dev", "sys", "system", "proc", "etc", "init", "d", "cache", "acct", "data" }; + + private void scan( File dir, int level ) + { + if ( level > 8 ) + { + return; + } + + try + { + if ( dir.isDirectory() ) + { + if ( level == 1 ) + { + String name = dir.getName(); + for( String veto: vetos ) + { + if ( veto.equals( name ) ) + { + return; + } + } + } + + testPath( dir.getPath() ); + File[] childs = dir.listFiles(); + if ( childs == null ) + { + return; + } + for ( File child : childs ) + { + scan( child, level+1 ); + } + } + } + catch (Exception e) + { + setLastError( e.toString() ); + } + } + + private void testPath( String path ) throws Exception + { + setCurrentDir( path ); + + testReader( new CoordinateReaderOsmAnd( path ) ); + testReader( new CoordinateReaderOsmAnd( path, true ) ); + testReader( new CoordinateReaderLocus( path ) ); + testReader( new CoordinateReaderOrux( path ) ); + } + + private void testReader( CoordinateReader cor ) throws Exception + { + long ts = cor.getTimeStamp(); + if ( ts > maxtimestamp ) + { + maxtimestamp = ts; + synchronized (currentDirSync) + { + bestGuess = cor.basedir; + } + } + else if ( ts > 0 && ts == maxtimestamp ) + { + synchronized (currentDirSync) + { + if ( cor.basedir.length() < bestGuess.length() ) + { + bestGuess = cor.basedir; + } + } + } + } + + @Override + public void run() + { + scan( new File( "/" ), 0 ); + setCurrentDir( null ); + + } +}