Reformat files using Android Studio

android-studio/bin/format.sh -m '*.java' -r brouter-routing-app

To rebase active branches on top of the new master just rebase your
branch onto the commit prior to the reformatting and format every commit
of your branch using (<commit> should be replaced by this commit)

git rebase \
        --strategy-option=theirs \
        --onto <commit> \
        --exec 'format.sh -m "*.java" -r brouter-routing-app' \
        --exec 'git commit --all --no-edit --amend' \
        <commit>~

To ignore this mass edit during git blame see `.git-blame-ignore-revs`
This commit is contained in:
Manuel Fuhr 2021-11-20 16:50:23 +01:00
parent 13e0e382c1
commit 54d5c5e943
18 changed files with 3025 additions and 3662 deletions

View file

@ -13,70 +13,58 @@ import android.os.Environment;
/** /**
* static logger interface to be used in the android app * static logger interface to be used in the android app
*/ */
public class AppLogger public class AppLogger {
{ private static FileWriter debugLogWriter = null;
private static FileWriter debugLogWriter = null; private static boolean initDone = false;
private static boolean initDone = false;
private static void init() private static void init() {
{ try {
try // open logfile if existing
{ File sd = Environment.getExternalStorageDirectory();
// open logfile if existing if (sd == null) return;
File sd = Environment.getExternalStorageDirectory(); File debugLog = new File(sd, "Android/media/btools.routingapp/brouter/brouterapp.txt");
if ( sd == null ) return; if (debugLog.exists()) {
File debugLog = new File( sd, "Android/media/btools.routingapp/brouter/brouterapp.txt" ); debugLogWriter = new FileWriter(debugLog, true);
if ( debugLog.exists() )
{
debugLogWriter = new FileWriter( debugLog, true );
}
} }
catch( IOException ioe ) {} } catch (IOException ioe) {
} }
}
/** /**
* log an info trace to the app log file, if any * log an info trace to the app log file, if any
*/ */
public static boolean isLogging() public static boolean isLogging() {
{ if (!initDone) {
if ( !initDone ) initDone = true;
{ init();
initDone = true; log("logging started at " + new Date());
init();
log( "logging started at " + new Date() );
}
return debugLogWriter != null;
} }
return debugLogWriter != null;
}
/** /**
* log an info trace to the app log file, if any * log an info trace to the app log file, if any
*/ */
public static void log( String msg ) public static void log(String msg) {
{ if (isLogging()) {
if ( isLogging() ) try {
{ debugLogWriter.write(msg);
try debugLogWriter.write('\n');
{ debugLogWriter.flush();
debugLogWriter.write( msg ); } catch (IOException e) {
debugLogWriter.write( '\n' ); throw new RuntimeException("cannot write brouterapp.txt: " + e);
debugLogWriter.flush();
}
catch( IOException e )
{
throw new RuntimeException( "cannot write brouterapp.txt: " + e );
}
} }
} }
}
/** /**
* Format an exception using * Format an exception using
*/ */
public static String formatThrowable( Throwable t ) public static String formatThrowable(Throwable t) {
{ StringWriter sw = new StringWriter();
StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw);
PrintWriter pw = new PrintWriter( sw ); t.printStackTrace(pw);
t.printStackTrace( pw ); return sw.toString();
return sw.toString(); }
}
} }

View file

@ -22,144 +22,136 @@ import android.util.Log;
public class BInstallerActivity extends Activity { public class BInstallerActivity extends Activity {
public static final String DOWNLOAD_ACTION = "btools.routingapp.download"; public static final String DOWNLOAD_ACTION = "btools.routingapp.download";
private static final int DIALOG_CONFIRM_DELETE_ID = 1; private static final int DIALOG_CONFIRM_DELETE_ID = 1;
private BInstallerView mBInstallerView; private BInstallerView mBInstallerView;
private PowerManager mPowerManager; private PowerManager mPowerManager;
private WakeLock mWakeLock; private WakeLock mWakeLock;
private DownloadReceiver myReceiver; private DownloadReceiver myReceiver;
public class DownloadReceiver extends BroadcastReceiver { public class DownloadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra("txt")) {
String txt = intent.getStringExtra("txt");
boolean ready = intent.getBooleanExtra("ready", false);
mBInstallerView.setState(txt, ready);
}
}
}
/** Called when the activity is first created. */
@Override
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
// Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
.getName());
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// instantiate our simulation view and set it as the activity's content
mBInstallerView = new BInstallerView(this);
setContentView(mBInstallerView);
}
@Override @Override
protected void onResume() { public void onReceive(Context context, Intent intent) {
super.onResume(); if (intent.hasExtra("txt")) {
/* String txt = intent.getStringExtra("txt");
* when the activity is resumed, we acquire a wake-lock so that the boolean ready = intent.getBooleanExtra("ready", false);
* screen stays on, since the user will likely not be fiddling with the mBInstallerView.setState(txt, ready);
* screen or buttons. }
*/
mWakeLock.acquire();
IntentFilter filter = new IntentFilter();
filter.addAction(DOWNLOAD_ACTION);
myReceiver = new DownloadReceiver();
registerReceiver(myReceiver, filter);
// Start the download manager
mBInstallerView.startInstaller();
} }
}
@Override
protected void onPause() {
super.onPause();
super.onPause(); /**
* Called when the activity is first created.
*/
@Override
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWakeLock.release(); // Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
} // Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
.getName());
@Override setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
public void onDestroy() {
super.onDestroy(); // instantiate our simulation view and set it as the activity's content
if (myReceiver != null) unregisterReceiver(myReceiver); mBInstallerView = new BInstallerView(this);
System.exit(0); setContentView(mBInstallerView);
} }
@Override
protected void onResume() {
super.onResume();
/*
* when the activity is resumed, we acquire a wake-lock so that the
* screen stays on, since the user will likely not be fiddling with the
* screen or buttons.
*/
mWakeLock.acquire();
IntentFilter filter = new IntentFilter();
filter.addAction(DOWNLOAD_ACTION);
myReceiver = new DownloadReceiver();
registerReceiver(myReceiver, filter);
// Start the download manager
mBInstallerView.startInstaller();
}
@Override
protected void onPause() {
super.onPause();
super.onPause();
mWakeLock.release();
}
@Override
public void onDestroy() {
super.onDestroy();
if (myReceiver != null) unregisterReceiver(myReceiver);
System.exit(0);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected Dialog onCreateDialog( int id ) protected Dialog onCreateDialog(int id) {
{
AlertDialog.Builder builder; AlertDialog.Builder builder;
switch ( id ) switch (id) {
{ case DIALOG_CONFIRM_DELETE_ID:
case DIALOG_CONFIRM_DELETE_ID: builder = new AlertDialog.Builder(this);
builder = new AlertDialog.Builder( this ); builder
builder .setTitle("Confirm Delete")
.setTitle( "Confirm Delete" ) .setMessage("Really delete?").setPositiveButton("Yes", new DialogInterface.OnClickListener() {
.setMessage( "Really delete?" ).setPositiveButton( "Yes", new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int id) {
{ mBInstallerView.deleteSelectedTiles();
public void onClick( DialogInterface dialog, int id ) }
{ }).setNegativeButton("No", new DialogInterface.OnClickListener() {
mBInstallerView.deleteSelectedTiles(); public void onClick(DialogInterface dialog, int id) {
} }
} ).setNegativeButton( "No", new DialogInterface.OnClickListener() });
{ return builder.create();
public void onClick( DialogInterface dialog, int id )
{
}
} );
return builder.create();
default: default:
return null; return null;
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showConfirmDelete() public void showConfirmDelete() {
{ showDialog(DIALOG_CONFIRM_DELETE_ID);
showDialog( DIALOG_CONFIRM_DELETE_ID );
} }
private Set<Integer> dialogIds = new HashSet<Integer>(); private Set<Integer> dialogIds = new HashSet<Integer>();
private void showNewDialog( int id ) private void showNewDialog(int id) {
{ if (dialogIds.contains(Integer.valueOf(id))) {
if ( dialogIds.contains( Integer.valueOf( id ) ) ) removeDialog(id);
{
removeDialog( id );
} }
dialogIds.add( Integer.valueOf( id ) ); dialogIds.add(Integer.valueOf(id));
showDialog( id ); showDialog(id);
} }
static public long getAvailableSpace (String baseDir) { static public long getAvailableSpace(String baseDir) {
StatFs stat = new StatFs(baseDir); StatFs stat = new StatFs(baseDir);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return stat.getAvailableBlocksLong()*stat.getBlockSizeLong(); return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
} } else {
else { return stat.getAvailableBlocks() * stat.getBlockSize();
return stat.getAvailableBlocks()*stat.getBlockSize();
} }
} }
} }

View file

@ -63,379 +63,309 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
private PowerManager mPowerManager; private PowerManager mPowerManager;
private WakeLock mWakeLock; private WakeLock mWakeLock;
/** Called when the activity is first created. */ /**
* Called when the activity is first created.
*/
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void onCreate( Bundle savedInstanceState ) public void onCreate(Bundle savedInstanceState) {
{ super.onCreate(savedInstanceState);
super.onCreate( savedInstanceState );
// Get an instance of the PowerManager // Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService( POWER_SERVICE ); mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
// Create a bright wake lock // Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName() ); mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName());
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass(); int memoryClass = am.getMemoryClass();
// instantiate our simulation view and set it as the activity's content // instantiate our simulation view and set it as the activity's content
mBRouterView = new BRouterView( this, memoryClass ); mBRouterView = new BRouterView(this, memoryClass);
mBRouterView.init(); mBRouterView.init();
setContentView( mBRouterView ); setContentView(mBRouterView);
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected Dialog onCreateDialog( int id ) protected Dialog onCreateDialog(int id) {
{
AlertDialog.Builder builder; AlertDialog.Builder builder;
builder = new AlertDialog.Builder( this ); builder = new AlertDialog.Builder(this);
builder.setCancelable(false); builder.setCancelable(false);
switch ( id ) switch (id) {
{ case DIALOG_SELECTPROFILE_ID:
case DIALOG_SELECTPROFILE_ID: builder.setTitle("Select a routing profile");
builder.setTitle( "Select a routing profile" ); builder.setItems(availableProfiles, new DialogInterface.OnClickListener() {
builder.setItems( availableProfiles, new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int item) {
{ selectedProfile = availableProfiles[item];
public void onClick( DialogInterface dialog, int item ) mBRouterView.startProcessing(selectedProfile);
{
selectedProfile = availableProfiles[item];
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_MAINACTION_ID:
builder.setTitle( "Select Main Action" );
builder
.setItems( new String[]
{ "Download Manager", "BRouter App" }, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int item )
{
if ( item == 0 )
startDownloadManager();
else
showDialog( DIALOG_SELECTPROFILE_ID );
}
}
)
.setNegativeButton( "Close", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
}
);
return builder.create();
case DIALOG_SHOW_DM_INFO_ID:
builder
.setTitle( "BRouter Download Manager" )
.setMessage(
"*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
+ "files which can be up to 170MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! "
+ "Download speed is restricted to 4 MBit/s." ).setPositiveButton( "I know", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
Intent intent = new Intent( BRouterActivity.this, BInstallerActivity.class );
startActivity( intent );
// finish();
}
} ).setNegativeButton( "Cancel", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_SHOW_WP_HELP_ID:
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_API23_HELP_ID:
builder
.setTitle( "Android >=6 limitations" )
.setMessage(
"You are using the BRouter APP on Android >= 6, where classic mode is no longer supported. "
+ "Reason is that security policy does not permit any longer to read the waypoint databases of other apps. "
+ "That's o.k. if you want to use BRouter in server-mode only, where the apps actively send the waypoints "
+ "via a remote procedure call to BRouter (And Locus can also send nogo areas). "
+ "So the only functions you need to start the BRouter App are 1) to initially define the base directory "
+ "2) to download routing data files and 3) to configure the profile mapping via the 'Server-Mode' button. "
+ "You will eventually not be able to define nogo-areas (OsmAnd, Orux) or to do "
+ "very long distance calculations. If you want to get classic mode back, you can manually install "
+ "the APK of the BRouter App from the release page ( http://brouter.de/brouter/revisions.html ), which "
+ "is still built against Android API 10, and does not have these limitations. "
).setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID:
builder
.setTitle( "Successfully prepared a timeout-free calculation" )
.setMessage(
"You successfully repeated a calculation that previously run into a timeout "
+ "when started from your map-tool. If you repeat the same request from your "
+ "maptool, with the exact same destination point and a close-by starting point, "
+ "this request is guaranteed not to time out." ).setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_SHOW_WP_SCANRESULT_ID:
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
.setTitle( "Local setup needs reset" )
.setMessage(
"You are currently using an old version of the lookup-table " + "together with routing data made for this old table. "
+ "Before downloading new datafiles made for the new table, "
+ "you have to reset your local setup by 'moving away' (or deleting) "
+ "your <basedir>/brouter directory and start a new setup by calling the " + "BRouter App again." )
.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_ROUTINGMODES_ID:
builder.setTitle( message );
builder.setMultiChoiceItems( routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
routingModesChecked[which] = isChecked;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.configureService( routingModes, routingModesChecked );
}
} );
return builder.create();
case DIALOG_EXCEPTION_ID:
builder.setTitle( "An Error occured" ).setMessage( errorMessage ).setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
mBRouterView.continueProcessing();
}
} );
return builder.create();
case DIALOG_TEXTENTRY_ID:
builder.setTitle( "Enter SDCARD base dir:" );
builder.setMessage( message );
final EditText input = new EditText( this );
input.setText( defaultbasedir );
builder.setView( input );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
String basedir = input.getText().toString();
mBRouterView.startSetup( new File(basedir), true );
}
} );
return builder.create();
case DIALOG_SELECTBASEDIR_ID:
builder.setTitle( "Choose brouter data base dir:" );
// builder.setMessage( message );
builder.setSingleChoiceItems( basedirOptions, 0, new DialogInterface.OnClickListener()
{
@Override
public void onClick( DialogInterface dialog, int item )
{
selectedBasedir = item;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
if ( selectedBasedir < availableBasedirs.size() )
{
mBRouterView.startSetup( availableBasedirs.get( selectedBasedir ), true );
} }
else });
{ return builder.create();
showDialog( DIALOG_TEXTENTRY_ID ); case DIALOG_MAINACTION_ID:
builder.setTitle("Select Main Action");
builder
.setItems(new String[]
{"Download Manager", "BRouter App"}, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0)
startDownloadManager();
else
showDialog(DIALOG_SELECTPROFILE_ID);
}
}
)
.setNegativeButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
}
);
return builder.create();
case DIALOG_SHOW_DM_INFO_ID:
builder
.setTitle("BRouter Download Manager")
.setMessage(
"*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
+ "files which can be up to 170MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! "
+ "Download speed is restricted to 4 MBit/s.").setPositiveButton("I know", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class);
startActivity(intent);
// finish();
} }
} }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
} ); public void onClick(DialogInterface dialog, int id) {
return builder.create();
case DIALOG_VIASELECT_ID:
builder.setTitle( "Check VIA Selection:" );
builder.setMultiChoiceItems( availableVias, getCheckedBooleanArray( availableVias.length ), new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
if ( isChecked )
{
selectedVias.add( availableVias[which] );
}
else
{
selectedVias.remove( availableVias[which] );
}
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateViaList( selectedVias );
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_NOGOSELECT_ID:
builder.setTitle( "Check NoGo Selection:" );
String[] nogoNames = new String[nogoList.size()];
for ( int i = 0; i < nogoList.size(); i++ )
nogoNames[i] = nogoList.get( i ).name;
final boolean[] nogoEnabled = getCheckedBooleanArray( nogoList.size() );
builder.setMultiChoiceItems( nogoNames, getCheckedBooleanArray( nogoNames.length ), new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
nogoEnabled[which] = isChecked;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateNogoList( nogoEnabled );
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? ( wpCount != -2 ? "Exit" : "Help") : ( wpCount == 0 ? "Select from" : "Select to/via" );
String rightLabel = wpCount < 2 ? ( wpCount == -3 ? "Help" : "Server-Mode" ) : "Calc Route";
builder.setTitle( title ).setMessage( errorMessage ).setPositiveButton( leftLabel, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
if ( wpCount == -2 )
{
showWaypointDatabaseHelp();
}
else if ( wpCount == -1 || wpCount == -3 )
{
finish(); finish();
} }
else });
{ return builder.create();
mBRouterView.pickWaypoints(); case DIALOG_SHOW_WP_HELP_ID:
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() {
} ).setNegativeButton( rightLabel, new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int id) {
{ finish();
public void onClick( DialogInterface dialog, int id )
{
if ( wpCount == -3 )
{
showRepeatTimeoutHelp();
} }
else if ( wpCount < 2 ) });
{ return builder.create();
mBRouterView.startConfigureService(); case DIALOG_SHOW_API23_HELP_ID:
builder
.setTitle("Android >=6 limitations")
.setMessage(
"You are using the BRouter APP on Android >= 6, where classic mode is no longer supported. "
+ "Reason is that security policy does not permit any longer to read the waypoint databases of other apps. "
+ "That's o.k. if you want to use BRouter in server-mode only, where the apps actively send the waypoints "
+ "via a remote procedure call to BRouter (And Locus can also send nogo areas). "
+ "So the only functions you need to start the BRouter App are 1) to initially define the base directory "
+ "2) to download routing data files and 3) to configure the profile mapping via the 'Server-Mode' button. "
+ "You will eventually not be able to define nogo-areas (OsmAnd, Orux) or to do "
+ "very long distance calculations. If you want to get classic mode back, you can manually install "
+ "the APK of the BRouter App from the release page ( http://brouter.de/brouter/revisions.html ), which "
+ "is still built against Android API 10, and does not have these limitations. "
).setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
} }
else });
{ return builder.create();
mBRouterView.finishWaypointSelection(); case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID:
mBRouterView.startProcessing( selectedProfile ); builder
.setTitle("Successfully prepared a timeout-free calculation")
.setMessage(
"You successfully repeated a calculation that previously run into a timeout "
+ "when started from your map-tool. If you repeat the same request from your "
+ "maptool, with the exact same destination point and a close-by starting point, "
+ "this request is guaranteed not to time out.").setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
} }
} });
} ); return builder.create();
return builder.create(); case DIALOG_SHOW_WP_SCANRESULT_ID:
case DIALOG_MODECONFIGOVERVIEW_ID: builder
builder.setTitle( "Success" ).setMessage( message ).setPositiveButton( "Exit", new DialogInterface.OnClickListener() .setTitle("Waypoint Database ")
{ .setMessage("Found Waypoint-Database(s) for maptool-dir: " + maptoolDirCandidate
public void onClick( DialogInterface dialog, int id ) + " Configure that?").setPositiveButton("Yes", new DialogInterface.OnClickListener() {
{ public void onClick(DialogInterface dialog, int id) {
finish(); mBRouterView.saveMaptoolDir(maptoolDirCandidate);
} }
} ); }).setNegativeButton("No", new DialogInterface.OnClickListener() {
return builder.create(); public void onClick(DialogInterface dialog, int id) {
case DIALOG_PICKWAYPOINT_ID: finish();
builder.setTitle( wpCount > 0 ? "Select to/via" : "Select from" ); }
builder.setItems( availableWaypoints, new DialogInterface.OnClickListener() });
{ return builder.create();
public void onClick( DialogInterface dialog, int item ) case DIALOG_OLDDATAHINT_ID:
{ builder
mBRouterView.updateWaypointList( availableWaypoints[item] ); .setTitle("Local setup needs reset")
mBRouterView.startProcessing( selectedProfile ); .setMessage(
} "You are currently using an old version of the lookup-table " + "together with routing data made for this old table. "
} ); + "Before downloading new datafiles made for the new table, "
return builder.create(); + "you have to reset your local setup by 'moving away' (or deleting) "
+ "your <basedir>/brouter directory and start a new setup by calling the " + "BRouter App again.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_ROUTINGMODES_ID:
builder.setTitle(message);
builder.setMultiChoiceItems(routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
routingModesChecked[which] = isChecked;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.configureService(routingModes, routingModesChecked);
}
});
return builder.create();
case DIALOG_EXCEPTION_ID:
builder.setTitle("An Error occured").setMessage(errorMessage).setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mBRouterView.continueProcessing();
}
});
return builder.create();
case DIALOG_TEXTENTRY_ID:
builder.setTitle("Enter SDCARD base dir:");
builder.setMessage(message);
final EditText input = new EditText(this);
input.setText(defaultbasedir);
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String basedir = input.getText().toString();
mBRouterView.startSetup(new File(basedir), true);
}
});
return builder.create();
case DIALOG_SELECTBASEDIR_ID:
builder.setTitle("Choose brouter data base dir:");
// builder.setMessage( message );
builder.setSingleChoiceItems(basedirOptions, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
selectedBasedir = item;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if (selectedBasedir < availableBasedirs.size()) {
mBRouterView.startSetup(availableBasedirs.get(selectedBasedir), true);
} else {
showDialog(DIALOG_TEXTENTRY_ID);
}
}
});
return builder.create();
case DIALOG_VIASELECT_ID:
builder.setTitle("Check VIA Selection:");
builder.setMultiChoiceItems(availableVias, getCheckedBooleanArray(availableVias.length), new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
selectedVias.add(availableVias[which]);
} else {
selectedVias.remove(availableVias[which]);
}
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.updateViaList(selectedVias);
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
case DIALOG_NOGOSELECT_ID:
builder.setTitle("Check NoGo Selection:");
String[] nogoNames = new String[nogoList.size()];
for (int i = 0; i < nogoList.size(); i++)
nogoNames[i] = nogoList.get(i).name;
final boolean[] nogoEnabled = getCheckedBooleanArray(nogoList.size());
builder.setMultiChoiceItems(nogoNames, getCheckedBooleanArray(nogoNames.length), new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
nogoEnabled[which] = isChecked;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.updateNogoList(nogoEnabled);
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? (wpCount != -2 ? "Exit" : "Help") : (wpCount == 0 ? "Select from" : "Select to/via");
String rightLabel = wpCount < 2 ? (wpCount == -3 ? "Help" : "Server-Mode") : "Calc Route";
default: builder.setTitle(title).setMessage(errorMessage).setPositiveButton(leftLabel, new DialogInterface.OnClickListener() {
return null; public void onClick(DialogInterface dialog, int id) {
if (wpCount == -2) {
showWaypointDatabaseHelp();
} else if (wpCount == -1 || wpCount == -3) {
finish();
} else {
mBRouterView.pickWaypoints();
}
}
}).setNegativeButton(rightLabel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (wpCount == -3) {
showRepeatTimeoutHelp();
} else if (wpCount < 2) {
mBRouterView.startConfigureService();
} else {
mBRouterView.finishWaypointSelection();
mBRouterView.startProcessing(selectedProfile);
}
}
});
return builder.create();
case DIALOG_MODECONFIGOVERVIEW_ID:
builder.setTitle("Success").setMessage(message).setPositiveButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_PICKWAYPOINT_ID:
builder.setTitle(wpCount > 0 ? "Select to/via" : "Select from");
builder.setItems(availableWaypoints, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
mBRouterView.updateWaypointList(availableWaypoints[item]);
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
default:
return null;
} }
} }
private boolean[] getCheckedBooleanArray( int size ) private boolean[] getCheckedBooleanArray(int size) {
{
boolean[] checked = new boolean[size]; boolean[] checked = new boolean[size];
for ( int i = 0; i < checked.length; i++ ) checked[i] = true; for (int i = 0; i < checked.length; i++) checked[i] = true;
return checked; return checked;
} }
@ -461,76 +391,63 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
private String maptoolDirCandidate; private String maptoolDirCandidate;
public boolean isOnline(Context context) public boolean isOnline(Context context) {
{
boolean result = false; boolean result = false;
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Network nw = connectivityManager.getActiveNetwork(); Network nw = connectivityManager.getActiveNetwork();
if (nw == null) return false; if (nw == null) return false;
NetworkCapabilities nwc = connectivityManager.getNetworkCapabilities(nw); NetworkCapabilities nwc = connectivityManager.getNetworkCapabilities(nw);
if (nwc == null)return false; if (nwc == null) return false;
result = nwc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) | result = nwc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) |
nwc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) | nwc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) |
nwc.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ; nwc.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET);
} else { } else {
NetworkInfo ni = connectivityManager.getActiveNetworkInfo(); NetworkInfo ni = connectivityManager.getActiveNetworkInfo();
if (ni == null) return false; if (ni == null) return false;
result = ni.getType() == ConnectivityManager.TYPE_WIFI || result = ni.getType() == ConnectivityManager.TYPE_WIFI ||
ni.getType() == ConnectivityManager.TYPE_MOBILE || ni.getType() == ConnectivityManager.TYPE_MOBILE ||
ni.getType() == ConnectivityManager.TYPE_ETHERNET; ni.getType() == ConnectivityManager.TYPE_ETHERNET;
} }
return result; return result;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectProfile( String[] items ) public void selectProfile(String[] items) {
{
availableProfiles = items; availableProfiles = items;
// if we have internet access, first show the main action dialog // if we have internet access, first show the main action dialog
if ( isOnline(this) ) if (isOnline(this)) {
{ showDialog(DIALOG_MAINACTION_ID);
showDialog( DIALOG_MAINACTION_ID ); } else {
} showDialog(DIALOG_SELECTPROFILE_ID);
else
{
showDialog( DIALOG_SELECTPROFILE_ID );
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void startDownloadManager() public void startDownloadManager() {
{ if (!mBRouterView.hasUpToDateLookups()) {
if ( !mBRouterView.hasUpToDateLookups() ) showDialog(DIALOG_OLDDATAHINT_ID);
{ } else {
showDialog( DIALOG_OLDDATAHINT_ID ); showDialog(DIALOG_SHOW_DM_INFO_ID);
}
else
{
showDialog( DIALOG_SHOW_DM_INFO_ID );
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectBasedir( ArrayList<File> items, String defaultBasedir, String message ) public void selectBasedir(ArrayList<File> items, String defaultBasedir, String message) {
{
this.defaultbasedir = defaultBasedir; this.defaultbasedir = defaultBasedir;
this.message = message; this.message = message;
availableBasedirs = items; availableBasedirs = items;
ArrayList<Long> dirFreeSizes = new ArrayList<Long>(); ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
for ( File f : items ) for (File f : items) {
{
long size = 0L; long size = 0L;
try try {
{ StatFs stat = new StatFs(f.getAbsolutePath());
StatFs stat = new StatFs( f.getAbsolutePath() );
size = (long) stat.getAvailableBlocks() * stat.getBlockSize(); size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
} } catch (Exception e) { /* ignore */ }
catch (Exception e) { /* ignore */ } dirFreeSizes.add(Long.valueOf(size));
dirFreeSizes.add( Long.valueOf( size ) );
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@ -540,94 +457,80 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
} }
int bdidx = 0; int bdidx = 0;
DecimalFormat df = new DecimalFormat( "###0.00" ); DecimalFormat df = new DecimalFormat("###0.00");
for ( int idx = 0; idx < availableBasedirs.size(); idx++ ) for (int idx = 0; idx < availableBasedirs.size(); idx++) {
{ basedirOptions[bdidx++] = availableBasedirs.get(idx) + " (" + df.format(dirFreeSizes.get(idx) / 1024. / 1024. / 1024.) + " GB free)";
basedirOptions[bdidx++] = availableBasedirs.get( idx ) + " (" + df.format( dirFreeSizes.get( idx ) / 1024. / 1024. / 1024. ) + " GB free)";
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
basedirOptions[bdidx] = "Enter path manually"; basedirOptions[bdidx] = "Enter path manually";
} }
showDialog( DIALOG_SELECTBASEDIR_ID ); showDialog(DIALOG_SELECTBASEDIR_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectRoutingModes( String[] modes, boolean[] modesChecked, String message ) public void selectRoutingModes(String[] modes, boolean[] modesChecked, String message) {
{
routingModes = modes; routingModes = modes;
routingModesChecked = modesChecked; routingModesChecked = modesChecked;
this.message = message; this.message = message;
showDialog( DIALOG_ROUTINGMODES_ID ); showDialog(DIALOG_ROUTINGMODES_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showModeConfigOverview( String message ) public void showModeConfigOverview(String message) {
{
this.message = message; this.message = message;
showDialog( DIALOG_MODECONFIGOVERVIEW_ID ); showDialog(DIALOG_MODECONFIGOVERVIEW_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectVias( String[] items ) public void selectVias(String[] items) {
{
availableVias = items; availableVias = items;
selectedVias = new HashSet<String>( availableVias.length ); selectedVias = new HashSet<String>(availableVias.length);
for ( String via : items ) for (String via : items)
selectedVias.add( via ); selectedVias.add(via);
showDialog( DIALOG_VIASELECT_ID ); showDialog(DIALOG_VIASELECT_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectWaypoint( String[] items ) public void selectWaypoint(String[] items) {
{
availableWaypoints = items; availableWaypoints = items;
showNewDialog( DIALOG_PICKWAYPOINT_ID ); showNewDialog(DIALOG_PICKWAYPOINT_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showWaypointDatabaseHelp() public void showWaypointDatabaseHelp() {
{ if (mBRouterView.canAccessSdCard) {
if ( mBRouterView.canAccessSdCard ) showNewDialog(DIALOG_SHOW_WP_HELP_ID);
{ } else {
showNewDialog( DIALOG_SHOW_WP_HELP_ID ); showNewDialog(DIALOG_SHOW_API23_HELP_ID);
}
else
{
showNewDialog( DIALOG_SHOW_API23_HELP_ID );
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showRepeatTimeoutHelp() public void showRepeatTimeoutHelp() {
{ showNewDialog(DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID);
showNewDialog( DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID );
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showWpDatabaseScanSuccess( String bestGuess ) public void showWpDatabaseScanSuccess(String bestGuess) {
{
maptoolDirCandidate = bestGuess; maptoolDirCandidate = bestGuess;
showNewDialog( DIALOG_SHOW_WP_SCANRESULT_ID ); showNewDialog(DIALOG_SHOW_WP_SCANRESULT_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectNogos( List<OsmNodeNamed> nogoList ) public void selectNogos(List<OsmNodeNamed> nogoList) {
{
this.nogoList = nogoList; this.nogoList = nogoList;
showDialog( DIALOG_NOGOSELECT_ID ); showDialog(DIALOG_NOGOSELECT_ID);
} }
private Set<Integer> dialogIds = new HashSet<Integer>(); private Set<Integer> dialogIds = new HashSet<Integer>();
private void showNewDialog( int id ) private void showNewDialog(int id) {
{ if (dialogIds.contains(Integer.valueOf(id))) {
if ( dialogIds.contains( Integer.valueOf( id ) ) ) removeDialog(id);
{
removeDialog( id );
} }
dialogIds.add( Integer.valueOf( id ) ); dialogIds.add(Integer.valueOf(id));
showDialog( id ); showDialog(id);
} }
private String errorMessage; private String errorMessage;
@ -635,24 +538,21 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
private int wpCount; private int wpCount;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showErrorMessage( String msg ) public void showErrorMessage(String msg) {
{
errorMessage = msg; errorMessage = msg;
showNewDialog( DIALOG_EXCEPTION_ID ); showNewDialog(DIALOG_EXCEPTION_ID);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void showResultMessage( String title, String msg, int wpCount ) public void showResultMessage(String title, String msg, int wpCount) {
{
errorMessage = msg; errorMessage = msg;
this.title = title; this.title = title;
this.wpCount = wpCount; this.wpCount = wpCount;
showNewDialog( DIALOG_SHOWRESULT_ID ); showNewDialog(DIALOG_SHOWRESULT_ID);
} }
@Override @Override
protected void onResume() protected void onResume() {
{
super.onResume(); super.onResume();
/* /*
* when the activity is resumed, we acquire a wake-lock so that the screen * when the activity is resumed, we acquire a wake-lock so that the screen
@ -663,8 +563,7 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
} }
@Override @Override
protected void onPause() protected void onPause() {
{
super.onPause(); super.onPause();
/* /*
* When the activity is paused, we make sure to stop the router * When the activity is paused, we make sure to stop the router
@ -681,7 +580,7 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED
} }
public ArrayList<File> getStorageDirectories () { public ArrayList<File> getStorageDirectories() {
ArrayList<File> list = null; ArrayList<File> list = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
list = new ArrayList<File>(Arrays.asList(getExternalMediaDirs())); list = new ArrayList<File>(Arrays.asList(getExternalMediaDirs()));
@ -693,7 +592,7 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
for (File f : list) { for (File f : list) {
if (f != null) { if (f != null) {
if (getStorageState(f).equals(Environment.MEDIA_MOUNTED)) if (getStorageState(f).equals(Environment.MEDIA_MOUNTED))
res.add (f); res.add(f);
} }
} }
@ -708,27 +607,25 @@ public class BRouterActivity extends Activity implements ActivityCompat.OnReques
boolean isWritable = false; boolean isWritable = false;
try { try {
File sd = Environment.getExternalStorageDirectory(); File sd = Environment.getExternalStorageDirectory();
File testDir = new File( sd, "brouter" ); File testDir = new File(sd, "brouter");
boolean didExist = testDir.isDirectory(); boolean didExist = testDir.isDirectory();
if ( !didExist ) if (!didExist) {
{
testDir.mkdir(); testDir.mkdir();
} }
File testFile = new File( testDir, "test" + System.currentTimeMillis() ); File testFile = new File(testDir, "test" + System.currentTimeMillis());
testFile.createNewFile(); testFile.createNewFile();
if ( testFile.exists() ) { if (testFile.exists()) {
testFile.delete(); testFile.delete();
isWritable = true; isWritable = true;
} }
} } catch (Throwable t) {
catch (Throwable t) {
// ignore // ignore
} }
return isWritable; return isWritable;
} }
@Override @Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) { public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) { if (requestCode == 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mBRouterView.startSetup(null, true); mBRouterView.startSetup(null, true);

View file

@ -33,123 +33,106 @@ import androidx.core.content.ContextCompat;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
public class BRouterService extends Service public class BRouterService extends Service {
{
@Override @Override
public IBinder onBind(Intent arg0) { public IBinder onBind(Intent arg0) {
Log.d(getClass().getSimpleName(), "onBind()"); Log.d(getClass().getSimpleName(), "onBind()");
return myBRouterServiceStub; return myBRouterServiceStub;
} }
private IBRouterService.Stub myBRouterServiceStub = new IBRouterService.Stub() private IBRouterService.Stub myBRouterServiceStub = new IBRouterService.Stub() {
{
@Override @Override
public String getTrackFromParams( Bundle params ) throws RemoteException public String getTrackFromParams(Bundle params) throws RemoteException {
{ logBundle(params);
logBundle( params );
BRouterWorker worker = new BRouterWorker(); BRouterWorker worker = new BRouterWorker();
// get base dir from private file // get base dir from private file
String baseDir = null; String baseDir = null;
InputStream configInput = null; InputStream configInput = null;
try try {
{ configInput = openFileInput("config15.dat");
configInput = openFileInput( "config15.dat" ); BufferedReader br = new BufferedReader(new InputStreamReader(configInput));
BufferedReader br = new BufferedReader( new InputStreamReader( configInput ) );
baseDir = br.readLine(); baseDir = br.readLine();
} } catch (Exception e) {
catch (Exception e) } finally {
{ if (configInput != null) try {
} configInput.close();
finally } catch (Exception ee) {
{ }
if ( configInput != null ) try { configInput.close(); } catch (Exception ee) {}
} }
worker.baseDir = baseDir; worker.baseDir = baseDir;
worker.segmentDir = new File (baseDir, "brouter/segments4" ); worker.segmentDir = new File(baseDir, "brouter/segments4");
String remoteProfile = params.getString( "remoteProfile" ); String remoteProfile = params.getString("remoteProfile");
if ( remoteProfile == null ) if (remoteProfile == null) {
{ remoteProfile = checkForTestDummy(baseDir);
remoteProfile = checkForTestDummy( baseDir );
} }
String errMsg = null; String errMsg = null;
if (remoteProfile != null ) { if (remoteProfile != null) {
errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile); errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile);
} else if (params.containsKey("profile")) { } else if (params.containsKey("profile")) {
String profile = params.getString( "profile" ); String profile = params.getString("profile");
worker.profileName = profile; worker.profileName = profile;
worker.profilePath = baseDir + "/brouter/profiles2/" + profile + ".brf"; worker.profilePath = baseDir + "/brouter/profiles2/" + profile + ".brf";
worker.rawTrackPath = baseDir + "/brouter/modes/" + profile + "_rawtrack.dat"; worker.rawTrackPath = baseDir + "/brouter/modes/" + profile + "_rawtrack.dat";
if (!new File(worker.profilePath).exists()) errMsg = "Profile " + profile + " does not exists"; if (!new File(worker.profilePath).exists())
errMsg = "Profile " + profile + " does not exists";
try { try {
readNogos(worker, baseDir); readNogos(worker, baseDir);
} catch (Exception e) { } catch (Exception e) {
errMsg = e.getLocalizedMessage(); errMsg = e.getLocalizedMessage();
} }
} } else {
else {
errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast")); errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast"));
} }
if ( errMsg != null ) if (errMsg != null) {
{
return errMsg; return errMsg;
} }
boolean canCompress = "true".equals( params.getString( "acceptCompressedResult" ) ); boolean canCompress = "true".equals(params.getString("acceptCompressedResult"));
try try {
{ String gpxMessage = worker.getTrackFromParams(params);
String gpxMessage = worker.getTrackFromParams( params ); if (canCompress && gpxMessage.startsWith("<")) {
if ( canCompress && gpxMessage.startsWith( "<" ) ) try {
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write( "z64".getBytes(Charset.forName("UTF-8")) ); // marker prefix baos.write("z64".getBytes(Charset.forName("UTF-8"))); // marker prefix
OutputStream os = new GZIPOutputStream( baos ); OutputStream os = new GZIPOutputStream(baos);
byte[] ab = gpxMessage.getBytes(Charset.forName("UTF-8")); //StandardCharsets.UTF_8 byte[] ab = gpxMessage.getBytes(Charset.forName("UTF-8")); //StandardCharsets.UTF_8
gpxMessage = null; gpxMessage = null;
os.write( ab ); os.write(ab);
ab = null; ab = null;
os.close(); os.close();
gpxMessage = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); gpxMessage = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
return gpxMessage; return gpxMessage;
} } catch (Exception e) {
catch( Exception e )
{
return "error compressing result"; return "error compressing result";
} }
} }
return gpxMessage; return gpxMessage;
} } catch (IllegalArgumentException iae) {
catch (IllegalArgumentException iae)
{
return iae.getMessage(); return iae.getMessage();
} }
} }
private String getConfigFromMode( BRouterWorker worker, String baseDir, String mode, String fast ) private String getConfigFromMode(BRouterWorker worker, String baseDir, String mode, String fast) {
{ boolean isFast = "1".equals(fast) || "true".equals(fast) || "yes".equals(fast);
boolean isFast = "1".equals( fast ) || "true".equals( fast ) || "yes".equals( fast ); String mode_key = mode + "_" + (isFast ? "fast" : "short");
String mode_key = mode + "_" + ( isFast ? "fast" : "short" );
BufferedReader br = null; BufferedReader br = null;
try try {
{
String modesFile = baseDir + "/brouter/modes/serviceconfig.dat"; String modesFile = baseDir + "/brouter/modes/serviceconfig.dat";
br = new BufferedReader( new FileReader( modesFile ) ); br = new BufferedReader(new FileReader(modesFile));
for ( ;; ) for (; ; ) {
{
String line = br.readLine(); String line = br.readLine();
if ( line == null ) if (line == null)
break; break;
ServiceModeConfig smc = new ServiceModeConfig( line ); ServiceModeConfig smc = new ServiceModeConfig(line);
if ( !smc.mode.equals( mode_key ) ) if (!smc.mode.equals(mode_key))
continue; continue;
worker.profileName = smc.profile; worker.profileName = smc.profile;
worker.profilePath = baseDir + "/brouter/profiles2/" + smc.profile + ".brf"; worker.profilePath = baseDir + "/brouter/profiles2/" + smc.profile + ".brf";
@ -159,48 +142,42 @@ public class BRouterService extends Service
return null; return null;
} }
} } catch (Exception e) {
catch (Exception e)
{
return "no brouter service config found, mode " + mode_key; return "no brouter service config found, mode " + mode_key;
} } finally {
finally if (br != null) try {
{ br.close();
if ( br != null ) try { br.close(); } catch( Exception ee ) {} } catch (Exception ee) {
}
} }
return "no brouter service config found for mode " + mode_key; return "no brouter service config found for mode " + mode_key;
} }
private String getConfigForRemoteProfile( BRouterWorker worker, String baseDir, String remoteProfile ) private String getConfigForRemoteProfile(BRouterWorker worker, String baseDir, String remoteProfile) {
{
worker.profileName = "remote"; worker.profileName = "remote";
worker.profilePath = baseDir + "/brouter/profiles2/remote.brf"; worker.profilePath = baseDir + "/brouter/profiles2/remote.brf";
worker.rawTrackPath = baseDir + "/brouter/modes/remote_rawtrack.dat"; worker.rawTrackPath = baseDir + "/brouter/modes/remote_rawtrack.dat";
// store profile only if not identical (to preserve timestamp) // store profile only if not identical (to preserve timestamp)
byte[] profileBytes = remoteProfile.getBytes(); byte[] profileBytes = remoteProfile.getBytes();
File profileFile = new File( worker.profilePath ); File profileFile = new File(worker.profilePath);
try try {
{
readNogos(worker, baseDir); readNogos(worker, baseDir);
if ( !fileEqual( profileBytes, profileFile ) ) if (!fileEqual(profileBytes, profileFile)) {
{
OutputStream os = null; OutputStream os = null;
try try {
{ os = new FileOutputStream(profileFile);
os = new FileOutputStream( profileFile ); os.write(profileBytes);
os.write( profileBytes ); } finally {
} if (os != null) try {
finally os.close();
{ } catch (IOException io) {
if ( os != null ) try { os.close(); } catch( IOException io ) {} }
} }
} }
} } catch (Exception e) {
catch( Exception e )
{
return "error caching remote profile: " + e; return "error caching remote profile: " + e;
} }
return null; return null;
@ -208,7 +185,7 @@ public class BRouterService extends Service
private void readNogos(BRouterWorker worker, String baseDir) throws Exception { private void readNogos(BRouterWorker worker, String baseDir) throws Exception {
// add nogos from waypoint database // add nogos from waypoint database
int deviceLevel = android.os.Build.VERSION.SDK_INT; int deviceLevel = android.os.Build.VERSION.SDK_INT;
int targetSdkVersion = getApplicationInfo().targetSdkVersion; int targetSdkVersion = getApplicationInfo().targetSdkVersion;
boolean canAccessSdCard = true; boolean canAccessSdCard = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) {
@ -217,18 +194,16 @@ public class BRouterService extends Service
if (ContextCompat.checkSelfPermission(BRouterService.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(BRouterService.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
canAccessSdCard = false; canAccessSdCard = false;
} }
AppLogger.log( "dev/target=" + deviceLevel + "/" + targetSdkVersion + " canAccessSdCard=" + canAccessSdCard ); AppLogger.log("dev/target=" + deviceLevel + "/" + targetSdkVersion + " canAccessSdCard=" + canAccessSdCard);
CoordinateReader cor = CoordinateReader.obtainValidReader( baseDir, worker.segmentDir, canAccessSdCard, true ); CoordinateReader cor = CoordinateReader.obtainValidReader(baseDir, worker.segmentDir, canAccessSdCard, true);
worker.nogoList = new ArrayList<OsmNodeNamed>( cor.nogopoints ); worker.nogoList = new ArrayList<OsmNodeNamed>(cor.nogopoints);
worker.nogoPolygonsList = new ArrayList<OsmNodeNamed>(); worker.nogoPolygonsList = new ArrayList<OsmNodeNamed>();
} }
private boolean fileEqual( byte[] fileBytes, File file ) throws Exception private boolean fileEqual(byte[] fileBytes, File file) throws Exception {
{ if (!file.exists()) {
if ( !file.exists() )
{
return false; return false;
} }
int nbytes = fileBytes.length; int nbytes = fileBytes.length;
@ -236,107 +211,92 @@ public class BRouterService extends Service
int blen = 8192; int blen = 8192;
byte[] buf = new byte[blen]; byte[] buf = new byte[blen];
InputStream is = null; InputStream is = null;
try try {
{ is = new FileInputStream(file);
is = new FileInputStream( file ); while (pos < nbytes) {
while( pos < nbytes ) int len = is.read(buf, 0, blen);
{ if (len <= 0) return false;
int len = is.read( buf, 0, blen ); if (pos + len > nbytes) return false;
if ( len <= 0 ) return false; for (int j = 0; j < len; j++) {
if ( pos + len > nbytes ) return false; if (fileBytes[pos++] != buf[j]) {
for( int j=0; j<len; j++ )
{
if ( fileBytes[pos++] != buf[j] )
{
return false; return false;
} }
} }
} }
return true; return true;
} } finally {
finally if (is != null) try {
{ is.close();
if ( is != null ) try { is.close(); } catch( IOException io ) {} } catch (IOException io) {
}
} }
} }
private String checkForTestDummy( String baseDir ) private String checkForTestDummy(String baseDir) {
{ File testdummy = new File(baseDir + "/brouter/profiles2/remotetestdummy.brf");
File testdummy = new File( baseDir + "/brouter/profiles2/remotetestdummy.brf" ); if (!testdummy.exists()) return null;
if ( !testdummy.exists() ) return null;
BufferedReader br = null; BufferedReader br = null;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
try try {
{ br = new BufferedReader(new FileReader(testdummy));
br = new BufferedReader( new FileReader( testdummy ) ); for (; ; ) {
for ( ;; )
{
String line = br.readLine(); String line = br.readLine();
if ( line == null ) if (line == null)
break; break;
sb.append( line ).append( '\n' ); sb.append(line).append('\n');
} }
return sb.toString(); return sb.toString();
} } catch (Exception e) {
catch (Exception e) throw new RuntimeException("error reading " + testdummy);
{ } finally {
throw new RuntimeException( "error reading " + testdummy ); if (br != null) try {
} br.close();
finally } catch (Exception ee) {
{
if ( br != null ) try { br.close(); } catch( Exception ee ) {}
}
}
private void logBundle( Bundle params )
{
if ( AppLogger.isLogging() )
{
for( String k : params.keySet() )
{
Object val = "remoteProfile".equals( k ) ? "<..cut..>" : params.get(k);
String desc = "key=" + k + (val == null ? "" : " class=" + val.getClass() + " val=" + val.toString() );
AppLogger.log( desc );
} }
} }
} }
}; private void logBundle(Bundle params) {
if (AppLogger.isLogging()) {
@Override for (String k : params.keySet()) {
public void onCreate() Object val = "remoteProfile".equals(k) ? "<..cut..>" : params.get(k);
{ String desc = "key=" + k + (val == null ? "" : " class=" + val.getClass() + " val=" + val.toString());
super.onCreate(); AppLogger.log(desc);
Log.d(getClass().getSimpleName(),"onCreate()"); }
} }
@Override
public void onDestroy()
{
super.onDestroy();
Log.d(getClass().getSimpleName(),"onDestroy()");
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
@SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId)
{
Log.d(getClass().getSimpleName(), "onStart()");
handleStart(intent, startId);
} }
@Override };
public int onStartCommand(Intent intent, int flags, int startId)
{
handleStart(intent, startId);
return START_STICKY;
}
void handleStart(Intent intent, int startId) @Override
{ public void onCreate() {
} super.onCreate();
Log.d(getClass().getSimpleName(), "onCreate()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(getClass().getSimpleName(), "onDestroy()");
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
@SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId) {
Log.d(getClass().getSimpleName(), "onStart()");
handleStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleStart(intent, startId);
return START_STICKY;
}
void handleStart(Intent intent, int startId) {
}
} }

View file

@ -17,8 +17,7 @@ import btools.router.OsmTrack;
import btools.router.RoutingContext; import btools.router.RoutingContext;
import btools.router.RoutingEngine; import btools.router.RoutingEngine;
public class BRouterWorker public class BRouterWorker {
{
private static final int OUTPUT_FORMAT_GPX = 0; private static final int OUTPUT_FORMAT_GPX = 0;
private static final int OUTPUT_FORMAT_KML = 1; private static final int OUTPUT_FORMAT_KML = 1;
private static final int OUTPUT_FORMAT_JSON = 2; private static final int OUTPUT_FORMAT_JSON = 2;
@ -32,119 +31,114 @@ public class BRouterWorker
public List<OsmNodeNamed> nogoList; public List<OsmNodeNamed> nogoList;
public List<OsmNodeNamed> nogoPolygonsList; public List<OsmNodeNamed> nogoPolygonsList;
public String getTrackFromParams(Bundle params) { public String getTrackFromParams(Bundle params) {
String pathToFileResult = params.getString("pathToFileResult"); String pathToFileResult = params.getString("pathToFileResult");
if (pathToFileResult != null) { if (pathToFileResult != null) {
File f = new File(pathToFileResult); File f = new File(pathToFileResult);
File dir = f.getParentFile(); File dir = f.getParentFile();
if (!dir.exists() || !dir.canWrite()) { if (!dir.exists() || !dir.canWrite()) {
return "file folder does not exists or can not be written!"; return "file folder does not exists or can not be written!";
}
} }
long maxRunningTime = 60000;
String sMaxRunningTime = params.getString("maxRunningTime");
if (sMaxRunningTime != null) {
maxRunningTime = Integer.parseInt(sMaxRunningTime) * 1000;
}
RoutingContext rc = new RoutingContext();
rc.rawTrackPath = rawTrackPath;
rc.localFunction = profilePath;
String tiFormat = params.getString("turnInstructionFormat");
if (tiFormat != null) {
if ("osmand".equalsIgnoreCase(tiFormat)) {
rc.turnInstructionMode = 3;
} else if ("locus".equalsIgnoreCase(tiFormat)) {
rc.turnInstructionMode = 2;
}
}
if (params.containsKey("timode")) {
rc.turnInstructionMode = params.getInt("timode");
}
if ( params.containsKey( "direction" ) )
{
rc.startDirection = params.getInt( "direction" );
}
if ( params.containsKey( "alternativeidx" ) ) {
rc.alternativeIdx = params.getInt( "alternativeidx" );
} }
readNogos( params ); // add interface provided nogos long maxRunningTime = 60000;
if ( nogoList != null ) { String sMaxRunningTime = params.getString("maxRunningTime");
RoutingContext.prepareNogoPoints(nogoList); if (sMaxRunningTime != null) {
if (rc.nogopoints == null) { maxRunningTime = Integer.parseInt(sMaxRunningTime) * 1000;
rc.nogopoints = nogoList; }
} else {
rc.nogopoints.addAll(nogoList); RoutingContext rc = new RoutingContext();
} rc.rawTrackPath = rawTrackPath;
rc.localFunction = profilePath;
String tiFormat = params.getString("turnInstructionFormat");
if (tiFormat != null) {
if ("osmand".equalsIgnoreCase(tiFormat)) {
rc.turnInstructionMode = 3;
} else if ("locus".equalsIgnoreCase(tiFormat)) {
rc.turnInstructionMode = 2;
}
}
if (params.containsKey("timode")) {
rc.turnInstructionMode = params.getInt("timode");
}
if (params.containsKey("direction")) {
rc.startDirection = params.getInt("direction");
}
if (params.containsKey("alternativeidx")) {
rc.alternativeIdx = params.getInt("alternativeidx");
}
readNogos(params); // add interface provided nogos
if (nogoList != null) {
RoutingContext.prepareNogoPoints(nogoList);
if (rc.nogopoints == null) {
rc.nogopoints = nogoList;
} else {
rc.nogopoints.addAll(nogoList);
}
} }
if (rc.nogopoints == null) { if (rc.nogopoints == null) {
rc.nogopoints = nogoPolygonsList; rc.nogopoints = nogoPolygonsList;
} else if ( nogoPolygonsList != null ) { } else if (nogoPolygonsList != null) {
rc.nogopoints.addAll(nogoPolygonsList); rc.nogopoints.addAll(nogoPolygonsList);
} }
List<OsmNodeNamed> poisList = readPoisList(params); List<OsmNodeNamed> poisList = readPoisList(params);
rc.poipoints = poisList; rc.poipoints = poisList;
if (params.containsKey("lats")) { if (params.containsKey("lats")) {
waypoints = readPositions(params); waypoints = readPositions(params);
} }
if (params.containsKey("lonlats")) { if (params.containsKey("lonlats")) {
waypoints = readLonlats(params); waypoints = readLonlats(params);
} }
if (waypoints == null) return "no pts "; if (waypoints == null) return "no pts ";
if (params.containsKey( "extraParams" )) { // add user params if (params.containsKey("extraParams")) { // add user params
String extraParams = params.getString("extraParams"); String extraParams = params.getString("extraParams");
if (rc.keyValues == null) rc.keyValues = new HashMap<String,String>(); if (rc.keyValues == null) rc.keyValues = new HashMap<String, String>();
StringTokenizer tk = new StringTokenizer( extraParams, "?&" ); StringTokenizer tk = new StringTokenizer(extraParams, "?&");
while( tk.hasMoreTokens() ) { while (tk.hasMoreTokens()) {
String t = tk.nextToken(); String t = tk.nextToken();
StringTokenizer tk2 = new StringTokenizer( t, "=" ); StringTokenizer tk2 = new StringTokenizer(t, "=");
if ( tk2.hasMoreTokens() ) { if (tk2.hasMoreTokens()) {
String key = tk2.nextToken(); String key = tk2.nextToken();
if ( tk2.hasMoreTokens() ) { if (tk2.hasMoreTokens()) {
String value = tk2.nextToken(); String value = tk2.nextToken();
rc.keyValues.put( key, value ); rc.keyValues.put(key, value);
}
}
} }
}
}
} }
try try {
{ writeTimeoutData(rc);
writeTimeoutData( rc ); } catch (Exception e) {
} }
catch( Exception e ) {}
RoutingEngine cr = new RoutingEngine( null, null, segmentDir, waypoints, rc ); RoutingEngine cr = new RoutingEngine(null, null, segmentDir, waypoints, rc);
cr.quite = true; cr.quite = true;
cr.doRun( maxRunningTime ); cr.doRun(maxRunningTime);
// store new reference track if any // store new reference track if any
// (can exist for timed-out search) // (can exist for timed-out search)
if ( cr.getFoundRawTrack() != null ) if (cr.getFoundRawTrack() != null) {
{ try {
try cr.getFoundRawTrack().writeBinary(rawTrackPath);
{ } catch (Exception e) {
cr.getFoundRawTrack().writeBinary( rawTrackPath );
} }
catch( Exception e ) {}
} }
if ( cr.getErrorMessage() != null ) if (cr.getErrorMessage() != null) {
{
return cr.getErrorMessage(); return cr.getErrorMessage();
} }
String format = params.getString("trackFormat"); String format = params.getString("trackFormat");
int writeFromat = OUTPUT_FORMAT_GPX; int writeFromat = OUTPUT_FORMAT_GPX;
if (format != null) { if (format != null) {
if ("kml".equals(format)) writeFromat = OUTPUT_FORMAT_KML; if ("kml".equals(format)) writeFromat = OUTPUT_FORMAT_KML;
@ -152,304 +146,281 @@ public class BRouterWorker
} }
OsmTrack track = cr.getFoundTrack(); OsmTrack track = cr.getFoundTrack();
if ( track != null ) if (track != null) {
{
if (params.containsKey("exportWaypoints")) { if (params.containsKey("exportWaypoints")) {
track.exportWaypoints = (params.getInt("exportWaypoints",0) == 1 ); track.exportWaypoints = (params.getInt("exportWaypoints", 0) == 1);
} }
if ( pathToFileResult == null ) if (pathToFileResult == null) {
{ switch (writeFromat) {
switch ( writeFromat ) { case OUTPUT_FORMAT_GPX:
case OUTPUT_FORMAT_GPX: return track.formatAsGpx(); return track.formatAsGpx();
case OUTPUT_FORMAT_KML: return track.formatAsKml(); case OUTPUT_FORMAT_KML:
case OUTPUT_FORMAT_JSON: return track.formatAsGeoJson(); return track.formatAsKml();
default: return track.formatAsGpx(); case OUTPUT_FORMAT_JSON:
return track.formatAsGeoJson();
default:
return track.formatAsGpx();
} }
} }
try try {
{ switch (writeFromat) {
switch ( writeFromat ) { case OUTPUT_FORMAT_GPX:
case OUTPUT_FORMAT_GPX: track.writeGpx(pathToFileResult); break; track.writeGpx(pathToFileResult);
case OUTPUT_FORMAT_KML: track.writeKml(pathToFileResult); break; break;
case OUTPUT_FORMAT_JSON: track.writeJson(pathToFileResult); break; case OUTPUT_FORMAT_KML:
default: track.writeGpx(pathToFileResult); break; track.writeKml(pathToFileResult);
break;
case OUTPUT_FORMAT_JSON:
track.writeJson(pathToFileResult);
break;
default:
track.writeGpx(pathToFileResult);
break;
} }
} } catch (Exception e) {
catch( Exception e ) return "error writing file: " + e;
{ }
return "error writing file: " + e; }
} return null;
}
return null;
} }
private List<OsmNodeNamed> readPositions( Bundle params ) private List<OsmNodeNamed> readPositions(Bundle params) {
{
List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>(); List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>();
double[] lats = params.getDoubleArray("lats"); double[] lats = params.getDoubleArray("lats");
double[] lons = params.getDoubleArray("lons"); double[] lons = params.getDoubleArray("lons");
if (lats == null || lats.length < 2 || lons == null || lons.length < 2) if (lats == null || lats.length < 2 || lons == null || lons.length < 2) {
{ throw new IllegalArgumentException("we need two lat/lon points at least!");
throw new IllegalArgumentException( "we need two lat/lon points at least!" ); }
}
for( int i=0; i<lats.length && i<lons.length; i++ ) for (int i = 0; i < lats.length && i < lons.length; i++) {
{
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
n.name = "via" + i; n.name = "via" + i;
n.ilon = (int)( ( lons[i] + 180. ) *1000000. + 0.5); n.ilon = (int) ((lons[i] + 180.) * 1000000. + 0.5);
n.ilat = (int)( ( lats[i] + 90. ) *1000000. + 0.5); n.ilat = (int) ((lats[i] + 90.) * 1000000. + 0.5);
wplist.add( n ); wplist.add(n);
} }
wplist.get(0).name = "from"; wplist.get(0).name = "from";
wplist.get(wplist.size()-1).name = "to"; wplist.get(wplist.size() - 1).name = "to";
return wplist; return wplist;
} }
private List<OsmNodeNamed> readLonlats(Bundle params ) private List<OsmNodeNamed> readLonlats(Bundle params) {
{ List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>();
List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>();
String lonLats = params.getString( "lonlats" ); String lonLats = params.getString("lonlats");
if (lonLats == null) throw new IllegalArgumentException( "lonlats parameter not set" ); if (lonLats == null) throw new IllegalArgumentException("lonlats parameter not set");
String[] coords = lonLats.split("\\|"); String[] coords = lonLats.split("\\|");
if (coords.length < 2) if (coords.length < 2)
throw new IllegalArgumentException( "we need two lat/lon points at least!" ); throw new IllegalArgumentException("we need two lat/lon points at least!");
for (int i = 0; i < coords.length; i++) for (int i = 0; i < coords.length; i++) {
{ String[] lonLat = coords[i].split(",");
String[] lonLat = coords[i].split(","); if (lonLat.length < 2)
if (lonLat.length < 2) throw new IllegalArgumentException("we need two lat/lon points at least!");
throw new IllegalArgumentException( "we need two lat/lon points at least!" ); wplist.add(readPosition(lonLat[0], lonLat[1], "via" + i));
wplist.add( readPosition( lonLat[0], lonLat[1], "via" + i ) );
}
wplist.get(0).name = "from";
wplist.get(wplist.size()-1).name = "to";
return wplist;
} }
private static OsmNodeNamed readPosition( String vlon, String vlat, String name ) wplist.get(0).name = "from";
{ wplist.get(wplist.size() - 1).name = "to";
if ( vlon == null ) throw new IllegalArgumentException( "lon " + name + " not found in input" );
if ( vlat == null ) throw new IllegalArgumentException( "lat " + name + " not found in input" );
return readPosition(Double.parseDouble( vlon ), Double.parseDouble( vlat ), name); return wplist;
} }
private static OsmNodeNamed readPosition( double lon, double lat, String name ) private static OsmNodeNamed readPosition(String vlon, String vlat, String name) {
{ if (vlon == null) throw new IllegalArgumentException("lon " + name + " not found in input");
OsmNodeNamed n = new OsmNodeNamed(); if (vlat == null) throw new IllegalArgumentException("lat " + name + " not found in input");
n.name = name;
n.ilon = (int)( ( lon + 180. ) *1000000. + 0.5); return readPosition(Double.parseDouble(vlon), Double.parseDouble(vlat), name);
n.ilat = (int)( ( lat + 90. ) *1000000. + 0.5); }
return n;
} private static OsmNodeNamed readPosition(double lon, double lat, String name) {
OsmNodeNamed n = new OsmNodeNamed();
n.name = name;
n.ilon = (int) ((lon + 180.) * 1000000. + 0.5);
n.ilat = (int) ((lat + 90.) * 1000000. + 0.5);
return n;
}
private void readNogos( Bundle params ) private void readNogos(Bundle params) {
{
if (params.containsKey("nogoLats")) { if (params.containsKey("nogoLats")) {
double[] lats = params.getDoubleArray("nogoLats"); double[] lats = params.getDoubleArray("nogoLats");
double[] lons = params.getDoubleArray("nogoLons"); double[] lons = params.getDoubleArray("nogoLons");
double[] radi = params.getDoubleArray("nogoRadi"); double[] radi = params.getDoubleArray("nogoRadi");
if (lats == null || lons == null || radi == null) return; if (lats == null || lons == null || radi == null) return;
for (int i = 0; i < lats.length && i < lons.length && i < radi.length; i++) { for (int i = 0; i < lats.length && i < lons.length && i < radi.length; i++) {
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
n.name = "nogo" + (int) radi[i]; n.name = "nogo" + (int) radi[i];
n.ilon = (int) ((lons[i] + 180.) * 1000000. + 0.5); n.ilon = (int) ((lons[i] + 180.) * 1000000. + 0.5);
n.ilat = (int) ((lats[i] + 90.) * 1000000. + 0.5); n.ilat = (int) ((lats[i] + 90.) * 1000000. + 0.5);
n.isNogo = true; n.isNogo = true;
n.nogoWeight = Double.NaN; n.nogoWeight = Double.NaN;
AppLogger.log("added interface provided nogo: " + n); AppLogger.log("added interface provided nogo: " + n);
nogoList.add(n); nogoList.add(n);
} }
} }
if (params.containsKey("nogos")) { if (params.containsKey("nogos")) {
nogoList = readNogoList(params); nogoList = readNogoList(params);
} }
if (params.containsKey("polylines") || if (params.containsKey("polylines") ||
params.containsKey("polygons")) { params.containsKey("polygons")) {
nogoPolygonsList = readNogoPolygons(params); nogoPolygonsList = readNogoPolygons(params);
} }
} }
private List<OsmNodeNamed> readNogoList(Bundle params) private List<OsmNodeNamed> readNogoList(Bundle params) {
{ // lon,lat,radius|...
// lon,lat,radius|... String nogos = params.getString("nogos");
String nogos = params.getString( "nogos" ); if (nogos == null) return null;
if ( nogos == null ) return null;
String[] lonLatRadList = nogos.split("\\|"); String[] lonLatRadList = nogos.split("\\|");
List<OsmNodeNamed> nogoList = new ArrayList<OsmNodeNamed>(); List<OsmNodeNamed> nogoList = new ArrayList<OsmNodeNamed>();
for (int i = 0; i < lonLatRadList.length; i++) for (int i = 0; i < lonLatRadList.length; i++) {
{ String[] lonLatRad = lonLatRadList[i].split(",");
String[] lonLatRad = lonLatRadList[i].split(","); String nogoWeight = "NaN";
String nogoWeight = "NaN"; if (lonLatRad.length > 3) {
if (lonLatRad.length > 3) { nogoWeight = lonLatRad[3];
nogoWeight = lonLatRad[3]; }
} nogoList.add(readNogo(lonLatRad[0], lonLatRad[1], lonLatRad[2], nogoWeight));
nogoList.add(readNogo(lonLatRad[0], lonLatRad[1], lonLatRad[2], nogoWeight)); }
return nogoList;
}
private static OsmNodeNamed readNogo(String lon, String lat, String radius, String nogoWeight) {
double weight = "undefined".equals(nogoWeight) ? Double.NaN : Double.parseDouble(nogoWeight);
return readNogo(Double.parseDouble(lon), Double.parseDouble(lat), Integer.parseInt(radius), weight);
}
private static OsmNodeNamed readNogo(double lon, double lat, int radius, double nogoWeight) {
OsmNodeNamed n = new OsmNodeNamed();
n.name = "nogo" + radius;
n.ilon = (int) ((lon + 180.) * 1000000. + 0.5);
n.ilat = (int) ((lat + 90.) * 1000000. + 0.5);
n.isNogo = true;
n.nogoWeight = nogoWeight;
return n;
}
private List<OsmNodeNamed> readNogoPolygons(Bundle params) {
List<OsmNodeNamed> result = new ArrayList<OsmNodeNamed>();
parseNogoPolygons(params.getString("polylines"), result, false);
parseNogoPolygons(params.getString("polygons"), result, true);
return result.size() > 0 ? result : null;
}
private static void parseNogoPolygons(String polygons, List<OsmNodeNamed> result, boolean closed) {
if (polygons != null) {
OsmNogoPolygon polygon = new OsmNogoPolygon(closed);
polygon.name = "nogopoly";
String nogoWeight = "NaN";
String[] polygonList = polygons.split("\\|");
for (int i = 0; i < polygonList.length; i++) {
String[] lonLatList = polygonList[i].split(",");
if (lonLatList.length > 1) {
int j;
for (j = 0; j < 2 * (lonLatList.length / 2) - 1; ) {
String slon = lonLatList[j++];
String slat = lonLatList[j++];
int lon = (int) ((Double.parseDouble(slon) + 180.) * 1000000. + 0.5);
int lat = (int) ((Double.parseDouble(slat) + 90.) * 1000000. + 0.5);
polygon.addVertex(lon, lat);
}
if (j < lonLatList.length) {
nogoWeight = lonLatList[j];
}
} }
}
polygon.nogoWeight = Double.parseDouble(nogoWeight);
return nogoList; if (polygon.points.size() > 0) {
polygon.calcBoundingCircle();
result.add(polygon);
}
} }
}
private static OsmNodeNamed readNogo( String lon, String lat, String radius, String nogoWeight ) private static void parseNogoPolygons_alt(String polygons, List<OsmNodeNamed> result, boolean closed) {
{ if (polygons != null) {
double weight = "undefined".equals( nogoWeight ) ? Double.NaN : Double.parseDouble( nogoWeight ); String[] polygonList = polygons.split("\\|");
return readNogo(Double.parseDouble( lon ), Double.parseDouble( lat ), Integer.parseInt( radius ), weight ); for (int i = 0; i < polygonList.length; i++) {
} String[] lonLatList = polygonList[i].split(",");
if (lonLatList.length > 1) {
OsmNogoPolygon polygon = new OsmNogoPolygon(closed);
polygon.name = "nogo" + i;
int j;
for (j = 0; j < 2 * (lonLatList.length / 2) - 1; ) {
String slon = lonLatList[j++];
String slat = lonLatList[j++];
int lon = (int) ((Double.parseDouble(slon) + 180.) * 1000000. + 0.5);
int lat = (int) ((Double.parseDouble(slat) + 90.) * 1000000. + 0.5);
polygon.addVertex(lon, lat);
}
private static OsmNodeNamed readNogo( double lon, double lat, int radius, double nogoWeight ) String nogoWeight = "NaN";
{ if (j < lonLatList.length) {
OsmNodeNamed n = new OsmNodeNamed(); nogoWeight = lonLatList[j];
n.name = "nogo" + radius; }
n.ilon = (int)( ( lon + 180. ) *1000000. + 0.5); polygon.nogoWeight = Double.parseDouble(nogoWeight);
n.ilat = (int)( ( lat + 90. ) *1000000. + 0.5);
n.isNogo = true;
n.nogoWeight = nogoWeight;
return n;
}
private List<OsmNodeNamed> readNogoPolygons(Bundle params) if (polygon.points.size() > 0) {
{ polygon.calcBoundingCircle();
List<OsmNodeNamed> result = new ArrayList<OsmNodeNamed>(); result.add(polygon);
parseNogoPolygons( params.getString("polylines"), result, false ); }
parseNogoPolygons( params.getString("polygons"), result, true );
return result.size() > 0 ? result : null;
}
private static void parseNogoPolygons(String polygons, List<OsmNodeNamed> result, boolean closed )
{
if ( polygons != null )
{
OsmNogoPolygon polygon = new OsmNogoPolygon(closed);
polygon.name = "nogopoly" ;
String nogoWeight = "NaN";
String[] polygonList = polygons.split("\\|");
for (int i = 0; i < polygonList.length; i++)
{
String[] lonLatList = polygonList[i].split(",");
if ( lonLatList.length > 1 )
{
int j;
for (j = 0; j < 2 * (lonLatList.length / 2) - 1;)
{
String slon = lonLatList[j++];
String slat = lonLatList[j++];
int lon = (int)( ( Double.parseDouble(slon) + 180. ) *1000000. + 0.5);
int lat = (int)( ( Double.parseDouble(slat) + 90. ) *1000000. + 0.5);
polygon.addVertex(lon, lat);
}
if (j < lonLatList.length) {
nogoWeight = lonLatList[j];
}
}
}
polygon.nogoWeight = Double.parseDouble( nogoWeight );
if ( polygon.points.size() > 0 )
{
polygon.calcBoundingCircle();
result.add(polygon);
}
} }
}
}
}
private List<OsmNodeNamed> readPoisList(Bundle params) {
// lon,lat,name|...
String pois = params.getString("pois");
if (pois == null) return null;
String[] lonLatNameList = pois.split("\\|");
List<OsmNodeNamed> poisList = new ArrayList<OsmNodeNamed>();
for (int i = 0; i < lonLatNameList.length; i++) {
String[] lonLatName = lonLatNameList[i].split(",");
OsmNodeNamed n = new OsmNodeNamed();
n.ilon = (int) ((Double.parseDouble(lonLatName[0]) + 180.) * 1000000. + 0.5);
n.ilat = (int) ((Double.parseDouble(lonLatName[1]) + 90.) * 1000000. + 0.5);
n.name = lonLatName[2];
poisList.add(n);
} }
private static void parseNogoPolygons_alt(String polygons, List<OsmNodeNamed> result, boolean closed ) return poisList;
{ }
if ( polygons != null )
{
String[] polygonList = polygons.split("\\|");
for (int i = 0; i < polygonList.length; i++)
{
String[] lonLatList = polygonList[i].split(",");
if ( lonLatList.length > 1 )
{
OsmNogoPolygon polygon = new OsmNogoPolygon(closed);
polygon.name = "nogo" + i;
int j;
for (j = 0; j < 2 * (lonLatList.length / 2) - 1;)
{
String slon = lonLatList[j++];
String slat = lonLatList[j++];
int lon = (int)( ( Double.parseDouble(slon) + 180. ) *1000000. + 0.5);
int lat = (int)( ( Double.parseDouble(slat) + 90. ) *1000000. + 0.5);
polygon.addVertex(lon, lat);
}
String nogoWeight = "NaN"; private void writeTimeoutData(RoutingContext rc) throws Exception {
if (j < lonLatList.length) {
nogoWeight = lonLatList[j];
}
polygon.nogoWeight = Double.parseDouble( nogoWeight );
if ( polygon.points.size() > 0 )
{
polygon.calcBoundingCircle();
result.add(polygon);
}
}
}
}
}
private List<OsmNodeNamed> readPoisList(Bundle params )
{
// lon,lat,name|...
String pois = params.getString( "pois" );
if ( pois == null ) return null;
String[] lonLatNameList = pois.split("\\|");
List<OsmNodeNamed> poisList = new ArrayList<OsmNodeNamed>();
for (int i = 0; i < lonLatNameList.length; i++)
{
String[] lonLatName = lonLatNameList[i].split(",");
OsmNodeNamed n = new OsmNodeNamed();
n.ilon = (int)( ( Double.parseDouble(lonLatName[0]) + 180. ) *1000000. + 0.5);
n.ilat = (int)( ( Double.parseDouble(lonLatName[1]) + 90. ) *1000000. + 0.5);
n.name = lonLatName[2];
poisList.add(n);
}
return poisList;
}
private void writeTimeoutData( RoutingContext rc ) throws Exception
{
String timeoutFile = baseDir + "/brouter/modes/timeoutdata.txt"; String timeoutFile = baseDir + "/brouter/modes/timeoutdata.txt";
BufferedWriter bw = new BufferedWriter( new FileWriter( timeoutFile ) ); BufferedWriter bw = new BufferedWriter(new FileWriter(timeoutFile));
bw.write( profileName ); bw.write(profileName);
bw.write( "\n" ); bw.write("\n");
bw.write( rc.rawTrackPath ); bw.write(rc.rawTrackPath);
bw.write( "\n" ); bw.write("\n");
writeWPList( bw, waypoints ); writeWPList(bw, waypoints);
writeWPList( bw, nogoList ); writeWPList(bw, nogoList);
bw.close(); bw.close();
} }
private void writeWPList( BufferedWriter bw, List<OsmNodeNamed> wps ) throws Exception private void writeWPList(BufferedWriter bw, List<OsmNodeNamed> wps) throws Exception {
{ bw.write(wps.size() + "\n");
bw.write( wps.size() + "\n" ); for (OsmNodeNamed wp : wps) {
for( OsmNodeNamed wp : wps ) bw.write(wp.toString());
{ bw.write("\n");
bw.write( wp.toString() );
bw.write( "\n" );
} }
} }
} }

View file

@ -10,31 +10,25 @@ import java.io.File;
import android.content.Context; import android.content.Context;
public class ConfigHelper public class ConfigHelper {
{ public static File getBaseDir(Context ctx) {
public static File getBaseDir( Context ctx )
{
// get base dir from private file // get base dir from private file
try (InputStream configInput = ctx.openFileInput( "config15.dat" ); try (InputStream configInput = ctx.openFileInput("config15.dat");
InputStreamReader isr = new InputStreamReader( configInput ); InputStreamReader isr = new InputStreamReader(configInput);
BufferedReader br = new BufferedReader(isr)) { BufferedReader br = new BufferedReader(isr)) {
return new File ( br.readLine() ); return new File(br.readLine());
} } catch (Exception e) {
catch (Exception e)
{
return null; return null;
} }
} }
public static void writeBaseDir( Context ctx, File baseDir ) public static void writeBaseDir(Context ctx, File baseDir) {
{ try (OutputStream configOutput = ctx.openFileOutput("config15.dat", Context.MODE_PRIVATE);
try (OutputStream configOutput = ctx.openFileOutput( "config15.dat", Context.MODE_PRIVATE ); OutputStreamWriter osw = new OutputStreamWriter(configOutput);
OutputStreamWriter osw = new OutputStreamWriter( configOutput ); BufferedWriter bw = new BufferedWriter(osw)) {
BufferedWriter bw = new BufferedWriter( osw)) { bw.write(baseDir.getAbsolutePath());
bw.write( baseDir.getAbsolutePath () ); bw.write('\n');
bw.write( '\n' ); } catch (Exception e) { /* ignore */ }
}
catch (Exception e){ /* ignore */ }
} }
} }

View file

@ -8,136 +8,101 @@ import java.io.FileWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ConfigMigration public class ConfigMigration {
{ public static void tryMigrateStorageConfig(File srcFile, File dstFile) {
public static void tryMigrateStorageConfig( File srcFile, File dstFile ) if (!srcFile.exists()) return;
{
if ( !srcFile.exists() ) return;
String ssd = null; String ssd = null;
String amd = null; String amd = null;
BufferedReader br = null; BufferedReader br = null;
BufferedWriter bw = null; BufferedWriter bw = null;
try try {
{ br = new BufferedReader(new FileReader(srcFile));
br = new BufferedReader( new FileReader( srcFile ) ); for (; ; ) {
for ( ;; )
{
String line = br.readLine(); String line = br.readLine();
if ( line == null ) break; if (line == null) break;
if ( line.trim().startsWith( "secondary_segment_dir=" ) ) if (line.trim().startsWith("secondary_segment_dir=")) {
{ if (!"secondary_segment_dir=../segments2".equals(line)) {
if ( !"secondary_segment_dir=../segments2".equals( line ) )
{
ssd = line; ssd = line;
} }
} }
if ( line.trim().startsWith( "additional_maptool_dir=" ) ) if (line.trim().startsWith("additional_maptool_dir=")) {
{
amd = line; amd = line;
} }
} }
br.close(); br.close();
List<String> lines = new ArrayList<String>(); List<String> lines = new ArrayList<String>();
br = new BufferedReader( new FileReader( dstFile ) ); br = new BufferedReader(new FileReader(dstFile));
for ( ;; ) for (; ; ) {
{
String line = br.readLine(); String line = br.readLine();
if ( line == null ) break; if (line == null) break;
if ( ssd != null && line.trim().startsWith( "secondary_segment_dir=" ) ) if (ssd != null && line.trim().startsWith("secondary_segment_dir=")) {
{
line = ssd; line = ssd;
} }
if ( amd != null && line.trim().startsWith( "#additional_maptool_dir=" ) ) if (amd != null && line.trim().startsWith("#additional_maptool_dir=")) {
{
line = amd; line = amd;
} }
lines.add( line ); lines.add(line);
} }
br.close(); br.close();
br = null; br = null;
bw = new BufferedWriter( new FileWriter( dstFile ) ); bw = new BufferedWriter(new FileWriter(dstFile));
for( String line: lines ) for (String line : lines) {
{ bw.write(line + "\n");
bw.write( line + "\n" );
} }
} } catch (Exception e) { /* ignore */ } finally {
catch (Exception e) { /* ignore */ } if (br != null) {
finally try {
{
if ( br != null )
{
try
{
br.close(); br.close();
} } catch (Exception ee) { /* ignore */ }
catch (Exception ee) { /* ignore */ }
} }
if ( bw != null ) if (bw != null) {
{ try {
try
{
bw.close(); bw.close();
} } catch (Exception ee) { /* ignore */ }
catch (Exception ee) { /* ignore */ }
} }
} }
} }
public static File saveAdditionalMaptoolDir( File segmentDir, String value ) public static File saveAdditionalMaptoolDir(File segmentDir, String value) {
{ return saveStorageLocation(segmentDir, "additional_maptool_dir=", value);
return saveStorageLocation( segmentDir, "additional_maptool_dir=", value );
} }
private static File saveStorageLocation( File segmentDir, String tag, String value ) private static File saveStorageLocation(File segmentDir, String tag, String value) {
{
File res = null; File res = null;
BufferedReader br = null; BufferedReader br = null;
BufferedWriter bw = null; BufferedWriter bw = null;
File configFile = new File (segmentDir, "storageconfig.txt"); File configFile = new File(segmentDir, "storageconfig.txt");
List<String> lines = new ArrayList<String>(); List<String> lines = new ArrayList<String>();
try try {
{ br = new BufferedReader(new FileReader(configFile));
br = new BufferedReader( new FileReader( configFile ) ); for (; ; ) {
for ( ;; )
{
String line = br.readLine(); String line = br.readLine();
if ( line == null ) break; if (line == null) break;
if ( !line.trim().startsWith( tag ) ) if (!line.trim().startsWith(tag)) {
{ lines.add(line);
lines.add( line );
} }
} }
lines.add( tag + value ); lines.add(tag + value);
br.close(); br.close();
br = null; br = null;
bw = new BufferedWriter( new FileWriter( configFile ) ); bw = new BufferedWriter(new FileWriter(configFile));
for( String line : lines ) for (String line : lines) {
{ bw.write(line + "\r\n");
bw.write( line + "\r\n" );
} }
} } catch (Exception e) { /* ignore */ } finally {
catch (Exception e) { /* ignore */ } if (br != null) {
finally try {
{
if ( br != null )
{
try
{
br.close(); br.close();
} } catch (Exception ee) { /* ignore */ }
catch (Exception ee) { /* ignore */ }
} }
if ( bw != null ) if (bw != null) {
{ try {
try
{
bw.close(); bw.close();
} } catch (Exception ee) { /* ignore */ }
catch (Exception ee) { /* ignore */ }
} }
} }
return res; return res;

View file

@ -11,14 +11,14 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import android.os.Environment; import android.os.Environment;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
import btools.router.RoutingHelper; import btools.router.RoutingHelper;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
*/ */
public abstract class CoordinateReader public abstract class CoordinateReader {
{
public List<OsmNodeNamed> waypoints; public List<OsmNodeNamed> waypoints;
public List<OsmNodeNamed> nogopoints; public List<OsmNodeNamed> nogopoints;
public String basedir; public String basedir;
@ -27,16 +27,15 @@ public abstract class CoordinateReader
private boolean nogosOnly; private boolean nogosOnly;
private Map<String,Map<String, OsmNodeNamed>> allpointsMap; private Map<String, Map<String, OsmNodeNamed>> allpointsMap;
public List<OsmNodeNamed> allpoints; public List<OsmNodeNamed> allpoints;
private HashMap<String,OsmNodeNamed> pointmap; private HashMap<String, OsmNodeNamed> pointmap;
protected static String[] posnames protected static String[] posnames
= new String[]{ "from", "via1", "via2", "via3", "via4", "via5", "via6", "via7", "via8", "via9", "to" }; = new String[]{"from", "via1", "via2", "via3", "via4", "via5", "via6", "via7", "via8", "via9", "to"};
public CoordinateReader( String basedir ) public CoordinateReader(String basedir) {
{
this.basedir = basedir; this.basedir = basedir;
} }
@ -44,30 +43,23 @@ public abstract class CoordinateReader
public abstract int getTurnInstructionMode(); public abstract int getTurnInstructionMode();
public void readAllPoints() throws Exception public void readAllPoints() throws Exception {
{ allpointsMap = new TreeMap<String, Map<String, OsmNodeNamed>>();
allpointsMap = new TreeMap<String, Map<String,OsmNodeNamed>>();
readFromTo(); readFromTo();
allpoints = new ArrayList<OsmNodeNamed>(); allpoints = new ArrayList<OsmNodeNamed>();
Set<String> names = new HashSet<String>(); Set<String> names = new HashSet<String>();
for( String category : allpointsMap.keySet() ) for (String category : allpointsMap.keySet()) {
{ Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
Map<String, OsmNodeNamed> cat = allpointsMap.get( category ); if (cat.size() < 101) {
if ( cat.size() < 101 ) for (OsmNodeNamed wp : cat.values()) {
{ if (names.add(wp.name)) {
for ( OsmNodeNamed wp : cat.values() ) allpoints.add(wp);
{
if ( names.add( wp.name ) )
{
allpoints.add( wp );
} }
} }
} } else {
else
{
OsmNodeNamed nocatHint = new OsmNodeNamed(); OsmNodeNamed nocatHint = new OsmNodeNamed();
nocatHint.name = "<big category " + category + " supressed>"; nocatHint.name = "<big category " + category + " supressed>";
allpoints.add( nocatHint); allpoints.add(nocatHint);
} }
} }
} }
@ -75,73 +67,57 @@ public abstract class CoordinateReader
/* /*
* read the from, to and via-positions from a gpx-file * read the from, to and via-positions from a gpx-file
*/ */
public void readFromTo() throws Exception public void readFromTo() throws Exception {
{ pointmap = new HashMap<String, OsmNodeNamed>();
pointmap = new HashMap<String,OsmNodeNamed>();
waypoints = new ArrayList<OsmNodeNamed>(); waypoints = new ArrayList<OsmNodeNamed>();
nogopoints = new ArrayList<OsmNodeNamed>(); nogopoints = new ArrayList<OsmNodeNamed>();
readPointmap(); readPointmap();
boolean fromToMissing = false; boolean fromToMissing = false;
for( int i=0; i<posnames.length; i++ ) for (int i = 0; i < posnames.length; i++) {
{
String name = posnames[i]; String name = posnames[i];
OsmNodeNamed n = pointmap.get(name); OsmNodeNamed n = pointmap.get(name);
if ( n != null ) if (n != null) {
{ waypoints.add(n);
waypoints.add( n ); } else {
} if ("from".equals(name)) fromToMissing = true;
else if ("to".equals(name)) fromToMissing = true;
{
if ( "from".equals( name ) ) fromToMissing = true;
if ( "to".equals( name ) ) fromToMissing = true;
} }
} }
if ( fromToMissing ) waypoints.clear(); if (fromToMissing) waypoints.clear();
} }
protected void checkAddPoint( String category, OsmNodeNamed n ) protected void checkAddPoint(String category, OsmNodeNamed n) {
{ if (allpointsMap != null) {
if ( allpointsMap != null ) if (category == null) category = "";
{ Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
if ( category == null ) category = ""; if (cat == null) {
Map<String, OsmNodeNamed> cat = allpointsMap.get( category );
if ( cat == null )
{
cat = new TreeMap<String, OsmNodeNamed>(); cat = new TreeMap<String, OsmNodeNamed>();
allpointsMap.put( category, cat ); allpointsMap.put(category, cat);
} }
if ( cat.size() < 101 ) if (cat.size() < 101) {
{ cat.put(n.name, n);
cat.put( n.name, n );
} }
return; return;
} }
boolean isKnown = false; boolean isKnown = false;
for( int i=0; i<posnames.length; i++ ) for (int i = 0; i < posnames.length; i++) {
{ if (posnames[i].equals(n.name)) {
if ( posnames[i].equals( n.name ) )
{
isKnown = true; isKnown = true;
break; break;
} }
} }
if ( isKnown ) if (isKnown) {
{ if (pointmap.put(n.name, n) != null) {
if ( pointmap.put( n.name, n ) != null ) if (!nogosOnly) {
{ throw new IllegalArgumentException("multiple " + n.name + "-positions!");
if ( !nogosOnly )
{
throw new IllegalArgumentException( "multiple " + n.name + "-positions!" );
} }
} }
} } else if (n.name != null && n.name.startsWith("nogo")) {
else if ( n.name != null && n.name.startsWith( "nogo" ) )
{
n.isNogo = true; n.isNogo = true;
n.nogoWeight = Double.NaN; n.nogoWeight = Double.NaN;
nogopoints.add( n ); nogopoints.add(n);
} }
} }
@ -149,13 +125,11 @@ public abstract class CoordinateReader
protected abstract void readPointmap() throws Exception; protected abstract void readPointmap() throws Exception;
public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean canAccessSdCard ) throws Exception public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard) throws Exception {
{ return obtainValidReader(basedir, segmentDir, canAccessSdCard, false);
return obtainValidReader( basedir, segmentDir, canAccessSdCard, false );
} }
public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean canAccessSdCard, boolean nogosOnly ) throws Exception public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard, boolean nogosOnly) throws Exception {
{
CoordinateReader cor = null; CoordinateReader cor = null;
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>(); ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
@ -210,8 +184,7 @@ public abstract class CoordinateReader
} }
} }
} }
if ( cor == null ) if (cor == null) {
{
cor = new CoordinateReaderInternal(basedir); cor = new CoordinateReaderInternal(basedir);
} }
cor.nogosOnly = nogosOnly; cor.nogosOnly = nogosOnly;

View file

@ -21,26 +21,20 @@ import btools.router.OsmNogoPolygon;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
*/ */
public class CoordinateReaderInternal extends CoordinateReader public class CoordinateReaderInternal extends CoordinateReader {
{
private String internalDir; private String internalDir;
public CoordinateReaderInternal(String basedir ) public CoordinateReaderInternal(String basedir) {
{ this(basedir, false);
this( basedir, false );
} }
public CoordinateReaderInternal(String basedir, boolean shortPath ) public CoordinateReaderInternal(String basedir, boolean shortPath) {
{ super(basedir);
super( basedir ); if (shortPath) {
if ( shortPath )
{
internalDir = basedir; internalDir = basedir;
tracksdir = "/tracks"; tracksdir = "/tracks";
rootdir = ""; rootdir = "";
} } else {
else
{
internalDir = basedir + "/brouter/import"; internalDir = basedir + "/brouter/import";
tracksdir = "/brouter/import/tracks"; tracksdir = "/brouter/import/tracks";
rootdir = "/brouter/import"; rootdir = "/brouter/import";
@ -48,16 +42,14 @@ public class CoordinateReaderInternal extends CoordinateReader
} }
@Override @Override
public long getTimeStamp() throws Exception public long getTimeStamp() throws Exception {
{ long t1 = new File(internalDir + "/favourites_bak.gpx").lastModified();
long t1 = new File( internalDir + "/favourites_bak.gpx" ).lastModified(); long t2 = new File(internalDir + "/favourites.gpx").lastModified();
long t2 = new File( internalDir + "/favourites.gpx" ).lastModified();
return t1 > t2 ? t1 : t2; return t1 > t2 ? t1 : t2;
} }
@Override @Override
public int getTurnInstructionMode() public int getTurnInstructionMode() {
{
return 4; // comment style return 4; // comment style
} }
@ -66,95 +58,78 @@ public class CoordinateReaderInternal extends CoordinateReader
* (with hardcoded name for now) * (with hardcoded name for now)
*/ */
@Override @Override
public void readPointmap() throws Exception public void readPointmap() throws Exception {
{ if (!_readPointmap(internalDir + "/favourites_bak.gpx")) {
if (! _readPointmap( internalDir + "/favourites_bak.gpx" ) ) { _readPointmap(internalDir + "/favourites.gpx");
_readPointmap( internalDir + "/favourites.gpx" );
} }
try try {
{ _readNogoLines(basedir + tracksdir);
_readNogoLines( basedir+tracksdir ); } catch (IOException ioe) {
}
catch( IOException ioe )
{
} }
} }
private boolean _readPointmap( String filename ) throws Exception private boolean _readPointmap(String filename) throws Exception {
{
BufferedReader br = null; BufferedReader br = null;
try { try {
br = new BufferedReader( br = new BufferedReader(
new InputStreamReader( new InputStreamReader(
new FileInputStream( filename ) ) ); new FileInputStream(filename)));
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
// ignore until it's reading error // ignore until it's reading error
return false; return false;
} }
OsmNodeNamed n = null; OsmNodeNamed n = null;
for(;;) for (; ; ) {
{ String line = br.readLine();
String line = br.readLine(); if (line == null) break;
if ( line == null ) break;
int idx0 = line.indexOf( " lat=\"" ); int idx0 = line.indexOf(" lat=\"");
int idx10 = line.indexOf( "<name>" ); int idx10 = line.indexOf("<name>");
if ( idx0 >= 0 ) if (idx0 >= 0) {
{ n = new OsmNodeNamed();
n = new OsmNodeNamed(); idx0 += 6;
idx0 += 6; int idx1 = line.indexOf('"', idx0);
int idx1 = line.indexOf( '"', idx0 ); n.ilat = (int) ((Double.parseDouble(line.substring(idx0, idx1)) + 90.) * 1000000. + 0.5);
n.ilat = (int)( (Double.parseDouble( line.substring( idx0, idx1 ) ) + 90. )*1000000. + 0.5); int idx2 = line.indexOf(" lon=\"");
int idx2 = line.indexOf( " lon=\"" ); if (idx2 < 0) continue;
if ( idx2 < 0 ) continue; idx2 += 6;
idx2 += 6; int idx3 = line.indexOf('"', idx2);
int idx3 = line.indexOf( '"', idx2 ); n.ilon = (int) ((Double.parseDouble(line.substring(idx2, idx3)) + 180.) * 1000000. + 0.5);
n.ilon = (int)( ( Double.parseDouble( line.substring( idx2, idx3 ) ) + 180. )*1000000. + 0.5); if (idx3 < 0) continue;
if ( idx3 < 0 ) continue; }
} if (n != null && idx10 >= 0) {
if ( n != null && idx10 >= 0 ) idx10 += 6;
{ int idx11 = line.indexOf("</name>", idx10);
idx10 += 6; if (idx11 >= 0) {
int idx11 = line.indexOf( "</name>", idx10 ); n.name = line.substring(idx10, idx11).trim();
if ( idx11 >= 0 ) checkAddPoint("(one-for-all)", n);
{
n.name = line.substring( idx10, idx11 ).trim();
checkAddPoint( "(one-for-all)", n );
}
} }
} }
br.close(); }
return true; br.close();
return true;
} }
private void _readNogoLines( String dirname ) throws IOException private void _readNogoLines(String dirname) throws IOException {
{
File dir = new File( dirname ); File dir = new File(dirname);
if (dir.exists() && dir.isDirectory()) if (dir.exists() && dir.isDirectory()) {
{ for (final File file : dir.listFiles()) {
for (final File file : dir.listFiles())
{
final String name = file.getName(); final String name = file.getName();
if (name.startsWith("nogo") && name.endsWith(".gpx")) if (name.startsWith("nogo") && name.endsWith(".gpx")) {
{ try {
try
{
_readNogoLine(file); _readNogoLine(file);
} } catch (Exception e) {
catch (Exception e)
{
} }
} }
} }
} }
} }
private void _readNogoLine( File file ) throws Exception private void _readNogoLine(File file) throws Exception {
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false); factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser(); XmlPullParser xpp = factory.newPullParser();
@ -165,45 +140,45 @@ public class CoordinateReaderInternal extends CoordinateReader
int eventType = xpp.getEventType(); int eventType = xpp.getEventType();
int numSeg = 0; int numSeg = 0;
while (eventType != XmlPullParser.END_DOCUMENT) { while (eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) { switch (eventType) {
case XmlPullParser.START_TAG: { case XmlPullParser.START_TAG: {
if (xpp.getName().equals("trkpt") || xpp.getName().equals("rtept")) { if (xpp.getName().equals("trkpt") || xpp.getName().equals("rtept")) {
final String lon = xpp.getAttributeValue(null,"lon"); final String lon = xpp.getAttributeValue(null, "lon");
final String lat = xpp.getAttributeValue(null,"lat"); final String lat = xpp.getAttributeValue(null, "lat");
if (lon != null && lat != null) { if (lon != null && lat != null) {
tmpPts.add(new Point( tmpPts.add(new Point(
(int)( ( Double.parseDouble(lon) + 180. ) *1000000. + 0.5), (int) ((Double.parseDouble(lon) + 180.) * 1000000. + 0.5),
(int)( ( Double.parseDouble(lat) + 90. ) *1000000. + 0.5)) ); (int) ((Double.parseDouble(lat) + 90.) * 1000000. + 0.5)));
}
} }
break;
} }
break; case XmlPullParser.END_TAG: {
} if (xpp.getName().equals("trkseg") || xpp.getName().equals("rte")) { // rte has no segment
case XmlPullParser.END_TAG: { OsmNogoPolygon nogo = null;
if (xpp.getName().equals("trkseg") || xpp.getName().equals("rte")) { // rte has no segment if (tmpPts.size() >= 0) {
OsmNogoPolygon nogo = null; if (tmpPts.get(0).x == tmpPts.get(tmpPts.size() - 1).x &&
if (tmpPts.size() >= 0) { tmpPts.get(0).y == tmpPts.get(tmpPts.size() - 1).y) {
if (tmpPts.get(0).x == tmpPts.get(tmpPts.size()-1).x && nogo = new OsmNogoPolygon(true);
tmpPts.get(0).y == tmpPts.get(tmpPts.size()-1).y) { } else {
nogo = new OsmNogoPolygon(true); nogo = new OsmNogoPolygon(false);
} else { }
nogo = new OsmNogoPolygon(false); for (Point p : tmpPts) {
nogo.addVertex(p.x, p.y);
}
nogo.calcBoundingCircle();
final String name = file.getName();
nogo.name = name.substring(0, name.length() - 4);
if (numSeg > 0) {
nogo.name += Integer.toString(numSeg + 1);
}
numSeg++;
checkAddPoint("(one-for-all)", nogo);
} }
for (Point p : tmpPts) { tmpPts.clear();
nogo.addVertex(p.x, p.y);
}
nogo.calcBoundingCircle();
final String name = file.getName();
nogo.name = name.substring(0, name.length() - 4);
if (numSeg > 0) {
nogo.name += Integer.toString(numSeg + 1);
}
numSeg++;
checkAddPoint("(one-for-all)", nogo);
} }
tmpPts.clear(); break;
} }
break;
}
} }
eventType = xpp.next(); eventType = xpp.next();
} }

View file

@ -4,24 +4,22 @@ import java.io.File;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
*/ */
public class CoordinateReaderLocus extends CoordinateReader public class CoordinateReaderLocus extends CoordinateReader {
{ public CoordinateReaderLocus(String basedir) {
public CoordinateReaderLocus( String basedir ) super(basedir);
{
super( basedir );
tracksdir = "/Locus/mapItems"; tracksdir = "/Locus/mapItems";
rootdir = "/Locus"; rootdir = "/Locus";
} }
@Override @Override
public long getTimeStamp() throws Exception public long getTimeStamp() throws Exception {
{ File f = new File(basedir + "/Locus/data/database/waypoints.db");
File f = new File( basedir + "/Locus/data/database/waypoints.db" );
long t1 = f.lastModified(); long t1 = f.lastModified();
// Android 10 delivers file size but can't read it // Android 10 delivers file size but can't read it
boolean canRead = f.canRead(); boolean canRead = f.canRead();
@ -29,8 +27,7 @@ public class CoordinateReaderLocus extends CoordinateReader
} }
@Override @Override
public int getTurnInstructionMode() public int getTurnInstructionMode() {
{
return 2; // locus style return 2; // locus style
} }
@ -39,16 +36,14 @@ public class CoordinateReaderLocus extends CoordinateReader
* (with hardcoded name for now) * (with hardcoded name for now)
*/ */
@Override @Override
public void readPointmap() throws Exception public void readPointmap() throws Exception {
{ _readPointmap(basedir + "/Locus/data/database/waypoints.db");
_readPointmap( basedir + "/Locus/data/database/waypoints.db" );
} }
private void _readPointmap( String filename ) throws Exception private void _readPointmap(String filename) throws Exception {
{
SQLiteDatabase myDataBase = null; SQLiteDatabase myDataBase = null;
try { try {
myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY); myDataBase = SQLiteDatabase.openDatabase(filename, null, SQLiteDatabase.OPEN_READONLY);
} catch (Exception e) { } catch (Exception e) {
// not open, do not produce an error // not open, do not produce an error
return; return;
@ -57,16 +52,15 @@ public class CoordinateReaderLocus extends CoordinateReader
Cursor c = myDataBase.rawQuery("SELECT c.name, w.name, w.longitude, w.latitude FROM waypoints w, categories c where w.parent_id = c._id", null); Cursor c = myDataBase.rawQuery("SELECT c.name, w.name, w.longitude, w.latitude FROM waypoints w, categories c where w.parent_id = c._id", null);
if (c.getCount() == 0) { if (c.getCount() == 0) {
c.close(); c.close();
c = myDataBase.rawQuery("SELECT c.name, w.name, w.longitude, w.latitude FROM waypoints w, groups c where w.parent_id = c._id;", null ); c = myDataBase.rawQuery("SELECT c.name, w.name, w.longitude, w.latitude FROM waypoints w, groups c where w.parent_id = c._id;", null);
} }
while (c.moveToNext()) while (c.moveToNext()) {
{
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
String category = c.getString(0); String category = c.getString(0);
n.name = c.getString(1); n.name = c.getString(1);
n.ilon = (int)( ( c.getDouble(2) + 180. )*1000000. + 0.5); n.ilon = (int) ((c.getDouble(2) + 180.) * 1000000. + 0.5);
n.ilat = (int)( ( c.getDouble(3) + 90. )*1000000. + 0.5); n.ilat = (int) ((c.getDouble(3) + 90.) * 1000000. + 0.5);
checkAddPoint( category, n ); checkAddPoint(category, n);
} }
c.close(); c.close();
myDataBase.close(); myDataBase.close();

View file

@ -4,24 +4,22 @@ import java.io.File;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
*/ */
public class CoordinateReaderOrux extends CoordinateReader public class CoordinateReaderOrux extends CoordinateReader {
{ public CoordinateReaderOrux(String basedir) {
public CoordinateReaderOrux( String basedir ) super(basedir);
{
super( basedir );
tracksdir = "/oruxmaps/tracklogs"; tracksdir = "/oruxmaps/tracklogs";
rootdir = "/oruxmaps"; rootdir = "/oruxmaps";
} }
@Override @Override
public long getTimeStamp() throws Exception public long getTimeStamp() throws Exception {
{ File f = new File(basedir + "/oruxmaps/tracklogs/oruxmapstracks.db");
File f = new File( basedir + "/oruxmaps/tracklogs/oruxmapstracks.db" );
long t1 = f.lastModified(); long t1 = f.lastModified();
// Android 10 delivers file size but can't read it // Android 10 delivers file size but can't read it
boolean canRead = f.canRead(); boolean canRead = f.canRead();
@ -29,8 +27,7 @@ public class CoordinateReaderOrux extends CoordinateReader
} }
@Override @Override
public int getTurnInstructionMode() public int getTurnInstructionMode() {
{
return 0; // none return 0; // none
} }
@ -39,29 +36,26 @@ public class CoordinateReaderOrux extends CoordinateReader
* (with hardcoded name for now) * (with hardcoded name for now)
*/ */
@Override @Override
public void readPointmap() throws Exception public void readPointmap() throws Exception {
{ _readPointmap(basedir + "/oruxmaps/tracklogs/oruxmapstracks.db");
_readPointmap( basedir + "/oruxmaps/tracklogs/oruxmapstracks.db" );
} }
private void _readPointmap( String filename ) throws Exception private void _readPointmap(String filename) throws Exception {
{
SQLiteDatabase myDataBase = null; SQLiteDatabase myDataBase = null;
try { try {
myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY); myDataBase = SQLiteDatabase.openDatabase(filename, null, SQLiteDatabase.OPEN_READONLY);
} catch (Exception e) { } catch (Exception e) {
// not open, do not produce an error // not open, do not produce an error
return; return;
} }
Cursor c = myDataBase.rawQuery("SELECT poiname, poilon, poilat, poifolder FROM pois", null); Cursor c = myDataBase.rawQuery("SELECT poiname, poilon, poilat, poifolder FROM pois", null);
while (c.moveToNext()) while (c.moveToNext()) {
{
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
n.name = c.getString(0); n.name = c.getString(0);
n.ilon = (int)( ( c.getDouble(1) + 180. )*1000000. + 0.5); n.ilon = (int) ((c.getDouble(1) + 180.) * 1000000. + 0.5);
n.ilat = (int)( ( c.getDouble(2) + 90. )*1000000. + 0.5); n.ilat = (int) ((c.getDouble(2) + 90.) * 1000000. + 0.5);
String category = c.getString(3); String category = c.getString(3);
checkAddPoint( category, n ); checkAddPoint(category, n);
} }
c.close(); c.close();
myDataBase.close(); myDataBase.close();

View file

@ -16,26 +16,20 @@ import btools.router.OsmNogoPolygon;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
*/ */
public class CoordinateReaderOsmAnd extends CoordinateReader public class CoordinateReaderOsmAnd extends CoordinateReader {
{
private String osmandDir; private String osmandDir;
public CoordinateReaderOsmAnd( String basedir ) public CoordinateReaderOsmAnd(String basedir) {
{ this(basedir, false);
this( basedir, false );
} }
public CoordinateReaderOsmAnd( String basedir, boolean shortPath ) public CoordinateReaderOsmAnd(String basedir, boolean shortPath) {
{ super(basedir);
super( basedir ); if (shortPath) {
if ( shortPath )
{
osmandDir = basedir; osmandDir = basedir;
tracksdir = "/tracks"; tracksdir = "/tracks";
rootdir = ""; rootdir = "";
} } else {
else
{
osmandDir = basedir + "/osmand"; osmandDir = basedir + "/osmand";
tracksdir = "/osmand/tracks"; tracksdir = "/osmand/tracks";
rootdir = "/osmand"; rootdir = "/osmand";
@ -43,18 +37,16 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
} }
@Override @Override
public long getTimeStamp() throws Exception public long getTimeStamp() throws Exception {
{ File f1 = new File(osmandDir + "/favourites_bak.gpx");
File f1 = new File( osmandDir + "/favourites_bak.gpx" ); File f2 = new File(osmandDir + "/favourites.gpx");
File f2 = new File( osmandDir + "/favourites.gpx" ); long t1 = f1.canRead() ? f1.lastModified() : 0L;
long t1 = f1.canRead()?f1.lastModified():0L; long t2 = f2.canRead() ? f2.lastModified() : 0L;
long t2 = f2.canRead()?f2.lastModified():0L;
return t1 > t2 ? t1 : t2; return t1 > t2 ? t1 : t2;
} }
@Override @Override
public int getTurnInstructionMode() public int getTurnInstructionMode() {
{
return 3; // osmand style return 3; // osmand style
} }
@ -63,92 +55,72 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
* (with hardcoded name for now) * (with hardcoded name for now)
*/ */
@Override @Override
public void readPointmap() throws Exception public void readPointmap() throws Exception {
{ try {
try _readPointmap(osmandDir + "/favourites_bak.gpx");
{ } catch (Exception e) {
_readPointmap( osmandDir + "/favourites_bak.gpx" ); _readPointmap(osmandDir + "/favourites.gpx");
} }
catch( Exception e ) try {
{ _readNogoLines(basedir + tracksdir);
_readPointmap( osmandDir + "/favourites.gpx" ); } catch (IOException ioe) {
}
try
{
_readNogoLines( basedir+tracksdir );
}
catch( IOException ioe )
{
} }
} }
private void _readPointmap( String filename ) throws Exception private void _readPointmap(String filename) throws Exception {
{ BufferedReader br = new BufferedReader(
BufferedReader br = new BufferedReader( new InputStreamReader(
new InputStreamReader( new FileInputStream(filename)));
new FileInputStream( filename ) ) ); OsmNodeNamed n = null;
OsmNodeNamed n = null;
for(;;) for (; ; ) {
{ String line = br.readLine();
String line = br.readLine(); if (line == null) break;
if ( line == null ) break;
int idx0 = line.indexOf( "<wpt lat=\"" ); int idx0 = line.indexOf("<wpt lat=\"");
int idx10 = line.indexOf( "<name>" ); int idx10 = line.indexOf("<name>");
if ( idx0 >= 0 ) if (idx0 >= 0) {
{ n = new OsmNodeNamed();
n = new OsmNodeNamed(); idx0 += 10;
idx0 += 10; int idx1 = line.indexOf('"', idx0);
int idx1 = line.indexOf( '"', idx0 ); n.ilat = (int) ((Double.parseDouble(line.substring(idx0, idx1)) + 90.) * 1000000. + 0.5);
n.ilat = (int)( (Double.parseDouble( line.substring( idx0, idx1 ) ) + 90. )*1000000. + 0.5); int idx2 = line.indexOf(" lon=\"");
int idx2 = line.indexOf( " lon=\"" ); if (idx2 < 0) continue;
if ( idx2 < 0 ) continue; idx2 += 6;
idx2 += 6; int idx3 = line.indexOf('"', idx2);
int idx3 = line.indexOf( '"', idx2 ); n.ilon = (int) ((Double.parseDouble(line.substring(idx2, idx3)) + 180.) * 1000000. + 0.5);
n.ilon = (int)( ( Double.parseDouble( line.substring( idx2, idx3 ) ) + 180. )*1000000. + 0.5); continue;
continue; }
} if (n != null && idx10 >= 0) {
if ( n != null && idx10 >= 0 ) idx10 += 6;
{ int idx11 = line.indexOf("</name>", idx10);
idx10 += 6; if (idx11 >= 0) {
int idx11 = line.indexOf( "</name>", idx10 ); n.name = line.substring(idx10, idx11).trim();
if ( idx11 >= 0 ) checkAddPoint("(one-for-all)", n);
{
n.name = line.substring( idx10, idx11 ).trim();
checkAddPoint( "(one-for-all)", n );
}
} }
} }
br.close(); }
br.close();
} }
private void _readNogoLines( String dirname ) throws IOException private void _readNogoLines(String dirname) throws IOException {
{
File dir = new File( dirname ); File dir = new File(dirname);
if (dir.exists() && dir.isDirectory()) if (dir.exists() && dir.isDirectory()) {
{ for (final File file : dir.listFiles()) {
for (final File file : dir.listFiles())
{
final String name = file.getName(); final String name = file.getName();
if (name.startsWith("nogo") && name.endsWith(".gpx")) if (name.startsWith("nogo") && name.endsWith(".gpx")) {
{ try {
try
{
_readNogoLine(file); _readNogoLine(file);
} } catch (Exception e) {
catch (Exception e)
{
} }
} }
} }
} }
} }
private void _readNogoLine( File file ) throws Exception private void _readNogoLine(File file) throws Exception {
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false); factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser(); XmlPullParser xpp = factory.newPullParser();
@ -158,33 +130,32 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
int eventType = xpp.getEventType(); int eventType = xpp.getEventType();
int numSeg = 0; int numSeg = 0;
while (eventType != XmlPullParser.END_DOCUMENT) { while (eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) { switch (eventType) {
case XmlPullParser.START_TAG: { case XmlPullParser.START_TAG: {
if (xpp.getName().equals("trkpt")) { if (xpp.getName().equals("trkpt")) {
final String lon = xpp.getAttributeValue(null,"lon"); final String lon = xpp.getAttributeValue(null, "lon");
final String lat = xpp.getAttributeValue(null,"lat"); final String lat = xpp.getAttributeValue(null, "lat");
if (lon != null && lat != null) { if (lon != null && lat != null) {
nogo.addVertex( nogo.addVertex(
(int)( ( Double.parseDouble(lon) + 180. ) *1000000. + 0.5), (int) ((Double.parseDouble(lon) + 180.) * 1000000. + 0.5),
(int)( ( Double.parseDouble(lat) + 90. ) *1000000. + 0.5)); (int) ((Double.parseDouble(lat) + 90.) * 1000000. + 0.5));
}
} }
break;
} }
break; case XmlPullParser.END_TAG: {
} if (xpp.getName().equals("trkseg")) {
case XmlPullParser.END_TAG: { nogo.calcBoundingCircle();
if (xpp.getName().equals("trkseg")) { final String name = file.getName();
nogo.calcBoundingCircle(); nogo.name = name.substring(0, name.length() - 4);
final String name = file.getName(); if (numSeg > 0) {
nogo.name = name.substring(0, name.length()-4); nogo.name += Integer.toString(numSeg + 1);
if (numSeg > 0) }
{ numSeg++;
nogo.name += Integer.toString(numSeg+1); checkAddPoint("(one-for-all)", nogo);
} }
numSeg++; break;
checkAddPoint( "(one-for-all)", nogo );
} }
break;
}
} }
eventType = xpp.next(); eventType = xpp.next();
} }

View file

@ -28,482 +28,460 @@ import btools.mapaccess.Rd5DiffManager;
import btools.mapaccess.Rd5DiffTool; import btools.mapaccess.Rd5DiffTool;
import btools.util.ProgressListener; import btools.util.ProgressListener;
public class DownloadService extends Service implements ProgressListener { public class DownloadService extends Service implements ProgressListener {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private ServerConfig mServerConfig; private ServerConfig mServerConfig;
private NotificationHelper mNotificationHelper; private NotificationHelper mNotificationHelper;
private List<String> mUrlList; private List<String> mUrlList;
private String baseDir; private String baseDir;
private volatile String newDownloadAction = ""; private volatile String newDownloadAction = "";
private volatile String currentDownloadOperation = ""; private volatile String currentDownloadOperation = "";
private long availableSize; private long availableSize;
private Looper mServiceLooper; private Looper mServiceLooper;
private ServiceHandler mServiceHandler; private ServiceHandler mServiceHandler;
private NotificationManager mNM; private NotificationManager mNM;
String downloadUrl; String downloadUrl;
public static boolean serviceState = false; public static boolean serviceState = false;
private boolean bIsDownloading; private boolean bIsDownloading;
// Handler that receives messages from the thread // Handler that receives messages from the thread
private final class ServiceHandler extends Handler { private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) { public ServiceHandler(Looper looper) {
super(looper); super(looper);
} }
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
bIsDownloading = true; bIsDownloading = true;
downloadFiles(); downloadFiles();
stopForeground(true); stopForeground(true);
stopSelf(msg.arg1); stopSelf(msg.arg1);
mNotificationHelper.stopNotification(); mNotificationHelper.stopNotification();
} }
}
@Override
public void onCreate() {
if (DEBUG) Log.d("SERVICE", "onCreate");
serviceState = true;
mServerConfig = new ServerConfig(getApplicationContext());
HandlerThread thread = new HandlerThread("ServiceStartArguments", 1);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
availableSize = -1;
try {
availableSize = BInstallerActivity.getAvailableSpace(baseDir);
//StatFs stat = new StatFs(baseDir);
//availableSize = (long)stat.getAvailableBlocksLong()*stat.getBlockSizeLong();
} catch (Exception e) { /* ignore */ }
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) Log.d("SERVICE", "onStartCommand");
mNotificationHelper = new NotificationHelper(this);
Bundle extra = intent.getExtras();
if (extra != null) {
String dir = extra.getString("dir");
List<String> urlparts = extra.getStringArrayList("urlparts");
mUrlList = urlparts;
baseDir = dir;
}
mNotificationHelper.startNotification(this);
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public void onDestroy() {
if (DEBUG) Log.d("SERVICE", "onDestroy");
serviceState = false;
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void downloadFiles() {
// first check lookup table and profiles
String result = checkScripts();
if (result != null) {
if (DEBUG) Log.d("BR", "error: " + result);
bIsDownloading = false;
updateProgress("finished ");
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
return;
} }
@Override int count = 1;
public void onCreate() { int size = mUrlList.size();
if (DEBUG) Log.d("SERVICE", "onCreate"); for (String part : mUrlList) {
serviceState = true; String url = mServerConfig.getSegmentUrl() + part + ".rd5";
mServerConfig = new ServerConfig(getApplicationContext()); if (DEBUG) Log.d("BR", "downlaod " + url);
HandlerThread thread = new HandlerThread("ServiceStartArguments", 1);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
availableSize = -1;
try
{
availableSize = BInstallerActivity.getAvailableSpace(baseDir);
//StatFs stat = new StatFs(baseDir);
//availableSize = (long)stat.getAvailableBlocksLong()*stat.getBlockSizeLong();
}
catch (Exception e) { /* ignore */ }
result = download(count, size, url);
if (result != null) {
if (DEBUG) Log.d("BR", "" + result);
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
break;
} else {
updateProgress("Download " + part + " " + count + "/" + size + " finshed");
}
count++;
} }
bIsDownloading = false;
updateProgress("finished ");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) Log.d("SERVICE", "onStartCommand");
mNotificationHelper = new NotificationHelper(this); public void updateProgress(String progress) {
Bundle extra = intent.getExtras(); if (!newDownloadAction.equals(progress)) {
if (extra != null) { if (DEBUG) Log.d("BR", "up " + progress);
String dir = extra.getString("dir"); Intent intent = new Intent(BInstallerActivity.DOWNLOAD_ACTION);
List<String> urlparts = extra.getStringArrayList("urlparts"); intent.putExtra("txt", progress);
mUrlList = urlparts; intent.putExtra("ready", bIsDownloading);
baseDir = dir; sendBroadcast(intent);
} ;
newDownloadAction = progress;
mNotificationHelper.startNotification(this); mNotificationHelper.progressUpdate(newDownloadAction);
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
} }
}
@Override private String download(int counter, int size, String surl) {
public void onDestroy() { InputStream input = null;
if (DEBUG) Log.d("SERVICE", "onDestroy"); OutputStream output = null;
serviceState = false; HttpURLConnection connection = null;
super.onDestroy(); File fname = null;
} File tmp_file = null;
try {
try {
TrafficStats.setThreadStatsTag(1);
int slidx = surl.lastIndexOf("segments4/");
String name = surl.substring(slidx + 10);
String surlBase = surl.substring(0, slidx + 10);
fname = new File(baseDir, "segments4/" + name);
@Override boolean delta = true;
public IBinder onBind(Intent intent) {
// if (!targetFile.getParentFile().exists()) targetFile.getParentFile().mkdirs();
if (fname.exists()) {
updateProgress("Calculating local checksum..");
// first check for a delta file
String md5 = Rd5DiffManager.getMD5(fname);
String surlDelta = surlBase + "diff/" + name.replace(".rd5", "/" + md5 + ".df5");
URL urlDelta = new URL(surlDelta);
connection = (HttpURLConnection) urlDelta.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
// 404 kind of expected here, means there's no delta file
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
connection = null;
} else {
updateProgress("Connecting.." + surlDelta);
}
}
if (connection == null) {
updateProgress("Connecting.." + name);
delta = false;
URL url = new URL(surl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
}
updateProgress("Connecting.." + counter + "/" + size);
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
long currentDownloadSize = fileLength;
if (availableSize >= 0 && fileLength > availableSize) return "not enough space on sd-card";
currentDownloadOperation = delta ? "Updating" : "Loading";
updateProgress(currentDownloadOperation);
// download the file
input = connection.getInputStream();
tmp_file = new File(fname.getAbsolutePath() + (delta ? "_diff" : "_tmp"));
output = new FileOutputStream(tmp_file);
byte[] data = new byte[4096];
long total = 0;
long t0 = System.currentTimeMillis();
int count;
while ((count = input.read(data)) != -1) {
if (isCanceled()) {
return "Download canceled!";
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
{
int pct = (int) (total * 100 / fileLength);
updateProgress("Progress " + counter + "/" + size + " .. " + pct + "%");
} else {
updateProgress("Progress (unnown size)");
}
output.write(data, 0, count);
// enforce < 2 Mbit/s
long dt = t0 + total / 524 - System.currentTimeMillis();
if (dt > 0) {
try {
Thread.sleep(dt);
} catch (InterruptedException ie) {
}
}
}
output.close();
output = null;
if (delta) {
updateProgress("Applying delta..");
File diffFile = tmp_file;
tmp_file = new File(fname + "_tmp");
Rd5DiffTool.recoverFromDelta(fname, diffFile, tmp_file, this);
diffFile.delete();
}
if (isCanceled()) {
return "Canceled!";
}
if (tmp_file != null) {
updateProgress("Verifying integrity..");
String check_result = PhysicalFile.checkFileIntegrity(tmp_file);
if (check_result != null) {
if (check_result.startsWith("version old lookups.dat")) {
}
return check_result;
}
if (fname.exists()) fname.delete();
if (!tmp_file.renameTo(fname)) {
return "Could not rename to " + fname.getAbsolutePath();
}
}
return null; return null;
} catch (Exception e) {
//e.printStackTrace(); ;
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
} finally {
if (tmp_file != null) tmp_file.delete(); // just to be sure
}
}
private String checkScripts() {
String[] sa = mServerConfig.getLookups();
for (String f : sa) {
if (f.length() > 0) {
File file = new File(baseDir + "profiles2", f);
checkOrDownloadLookup(f, file);
}
} }
sa = mServerConfig.getProfiles();
for (String f : sa) {
if (f.length() > 0) {
File file = new File(baseDir + "profiles2", f);
if (file.exists()) {
String result = checkOrDownloadScript(f, file);
if (result != null) {
return result;
}
}
}
}
return null;
}
public void downloadFiles() { private String checkOrDownloadLookup(String fileName, File f) {
String url = mServerConfig.getLookupUrl() + fileName;
return downloadScript(url, f);
}
// first check lookup table and profiles private String checkOrDownloadScript(String fileName, File f) {
String result = checkScripts(); String url = mServerConfig.getProfilesUrl() + fileName;
if ( result != null) { return downloadScript(url, f);
if (DEBUG) Log.d("BR", "error: " + result); }
bIsDownloading = false;
updateProgress( "finished " );
Toast.makeText(this, result, Toast.LENGTH_LONG).show(); private String downloadScript(String surl, File f) {
return; long size = 0L;
if (f.exists()) {
size = f.length();
}
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
File tmp_file = null;
File targetFile = f;
try {
try {
TrafficStats.setThreadStatsTag(1);
URL url = new URL(surl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
return null;
}
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage() + " " + f.getName();
} }
int count = 1; // this will be useful to display download percentage
int size = mUrlList.size(); // might be -1: server did not report the length
for (String part: mUrlList) { long fileLength = (long) connection.getContentLength();
String url = mServerConfig.getSegmentUrl() + part + ".rd5"; if (DEBUG) Log.d("BR", "file size " + size + " == " + fileLength + " " + f.getName());
if (DEBUG) Log.d("BR", "downlaod " + url); if (fileLength != size) {
long currentDownloadSize = fileLength;
if (availableSize >= 0 && fileLength > availableSize)
return "not enough space on sd-card";
result = download(count, size, url); currentDownloadOperation = "Updating";
if (result != null) {
if (DEBUG) Log.d("BR", "" + result); // download the file
Toast.makeText(this, result, Toast.LENGTH_LONG).show(); input = connection.getInputStream();
break;
tmp_file = new File(f.getAbsolutePath() + "_tmp");
output = new FileOutputStream(tmp_file);
byte data[] = new byte[4096];
long total = 0;
long t0 = System.currentTimeMillis();
int count;
while ((count = input.read(data)) != -1) {
if (isCanceled()) {
return "Download canceled!";
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
{
int pct = (int) (total * 100 / fileLength);
updateProgress("Progress " + pct + "%");
} else { } else {
updateProgress( "Download " + part + " " + count + "/"+ size + " finshed"); updateProgress("Progress (unnown size)");
} }
count++;
}
bIsDownloading = false; output.write(data, 0, count);
updateProgress( "finished " );
}
// enforce < 2 Mbit/s
public void updateProgress( String progress ) long dt = t0 + total / 524 - System.currentTimeMillis();
{ if (dt > 0) {
if ( !newDownloadAction.equals( progress ) ) try {
{ Thread.sleep(dt);
if (DEBUG) Log.d("BR", "up " + progress); } catch (InterruptedException ie) {
Intent intent = new Intent(BInstallerActivity.DOWNLOAD_ACTION); }
intent.putExtra("txt", progress);
intent.putExtra("ready", bIsDownloading);
sendBroadcast(intent);;
newDownloadAction = progress;
mNotificationHelper.progressUpdate(newDownloadAction);
}
}
private String download(int counter, int size, String surl)
{
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
File fname = null;
File tmp_file = null;
try
{
try
{
TrafficStats.setThreadStatsTag(1);
int slidx = surl.lastIndexOf( "segments4/" );
String name = surl.substring( slidx+10 );
String surlBase = surl.substring( 0, slidx+10 );
fname = new File (baseDir, "segments4/" + name);
boolean delta = true;
// if (!targetFile.getParentFile().exists()) targetFile.getParentFile().mkdirs();
if ( fname.exists() )
{
updateProgress( "Calculating local checksum.." );
// first check for a delta file
String md5 = Rd5DiffManager.getMD5( fname );
String surlDelta = surlBase + "diff/" + name.replace( ".rd5", "/" + md5 + ".df5" );
URL urlDelta = new URL(surlDelta);
connection = (HttpURLConnection) urlDelta.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
// 404 kind of expected here, means there's no delta file
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND )
{
connection = null;
} else {
updateProgress( "Connecting.." + surlDelta );
}
}
if ( connection == null )
{
updateProgress( "Connecting.." + name );
delta = false;
URL url = new URL(surl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
}
updateProgress( "Connecting.." + counter + "/"+size );
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
long currentDownloadSize = fileLength;
if ( availableSize >= 0 && fileLength > availableSize ) return "not enough space on sd-card";
currentDownloadOperation = delta ? "Updating" : "Loading";
updateProgress( currentDownloadOperation);
// download the file
input = connection.getInputStream();
tmp_file = new File( fname.getAbsolutePath() + ( delta ? "_diff" : "_tmp" ) );
output = new FileOutputStream( tmp_file );
byte[] data = new byte[4096];
long total = 0;
long t0 = System.currentTimeMillis();
int count;
while ((count = input.read(data)) != -1) {
if (isCanceled()) {
return "Download canceled!";
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
{
int pct = (int) (total * 100 / fileLength);
updateProgress( "Progress " + counter + "/"+size + " .. " + pct + "%" );
}
else
{
updateProgress( "Progress (unnown size)" );
}
output.write(data, 0, count);
// enforce < 2 Mbit/s
long dt = t0 + total/524 - System.currentTimeMillis();
if ( dt > 0 )
{
try { Thread.sleep( dt ); } catch( InterruptedException ie ) {}
}
}
output.close();
output = null;
if ( delta )
{
updateProgress( "Applying delta.." );
File diffFile = tmp_file;
tmp_file = new File( fname + "_tmp" );
Rd5DiffTool.recoverFromDelta( fname, diffFile, tmp_file, this );
diffFile.delete();
}
if (isCanceled())
{
return "Canceled!";
}
if ( tmp_file != null )
{
updateProgress( "Verifying integrity.." );
String check_result = PhysicalFile.checkFileIntegrity( tmp_file );
if ( check_result != null ) {
if (check_result.startsWith("version old lookups.dat") ) {
}
return check_result;
}
if (fname.exists()) fname.delete();
if ( !tmp_file.renameTo( fname ) )
{
return "Could not rename to " + fname.getAbsolutePath();
}
}
return null;
} catch (Exception e) {
//e.printStackTrace(); ;
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
}
finally
{
if ( tmp_file != null ) tmp_file.delete(); // just to be sure
}
}
private String checkScripts() {
String[] sa = mServerConfig.getLookups();
for (String f: sa) {
if (f.length()>0) {
File file = new File(baseDir + "profiles2", f);
checkOrDownloadLookup(f, file);
} }
}
output.close();
output = null;
} }
sa = mServerConfig.getProfiles(); if (isCanceled()) {
for (String f : sa) { return "Canceled!";
if (f.length()>0) { }
File file = new File(baseDir + "profiles2", f); if (tmp_file != null) {
if (file.exists()) { f.delete();
String result = checkOrDownloadScript(f, file);
if (result != null) { if (!tmp_file.renameTo(f)) {
return result; return "Could not rename to " + f.getName();
} }
} if (DEBUG) Log.d("BR", "update " + f.getName());
}
} }
return null; return null;
} } catch (Exception e) {
return e.toString();
private String checkOrDownloadLookup(String fileName, File f) { } finally {
String url = mServerConfig.getLookupUrl() + fileName; try {
return downloadScript(url, f); if (output != null)
} output.close();
if (input != null)
private String checkOrDownloadScript(String fileName, File f) { input.close();
String url = mServerConfig.getProfilesUrl() + fileName; } catch (IOException ignored) {
return downloadScript(url, f);
}
private String downloadScript(String surl, File f) {
long size = 0L;
if (f.exists()) {
size = f.length();
} }
InputStream input = null; if (connection != null)
OutputStream output = null; connection.disconnect();
HttpURLConnection connection = null;
File tmp_file = null;
File targetFile = f;
try
{
try
{
TrafficStats.setThreadStatsTag(1);
URL url = new URL(surl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
return null;
}
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage() + " " + f.getName();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
long fileLength = (long)connection.getContentLength();
if (DEBUG) Log.d("BR", "file size " + size + " == " + fileLength + " " + f.getName());
if (fileLength != size) {
long currentDownloadSize = fileLength;
if (availableSize >= 0 && fileLength > availableSize)
return "not enough space on sd-card";
currentDownloadOperation = "Updating";
// download the file
input = connection.getInputStream();
tmp_file = new File(f.getAbsolutePath() + "_tmp");
output = new FileOutputStream(tmp_file);
byte data[] = new byte[4096];
long total = 0;
long t0 = System.currentTimeMillis();
int count;
while ((count = input.read(data)) != -1) {
if (isCanceled()) {
return "Download canceled!";
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
{
int pct = (int) (total * 100 / fileLength);
updateProgress("Progress " + pct + "%");
} else {
updateProgress("Progress (unnown size)");
}
output.write(data, 0, count);
// enforce < 2 Mbit/s
long dt = t0 + total / 524 - System.currentTimeMillis();
if (dt > 0) {
try {
Thread.sleep(dt);
} catch (InterruptedException ie) {
}
}
}
output.close();
output = null;
}
if (isCanceled())
{
return "Canceled!";
}
if ( tmp_file != null )
{
f.delete();
if ( !tmp_file.renameTo( f ) )
{
return "Could not rename to " + f.getName();
}
if (DEBUG) Log.d("BR", "update " + f.getName());
}
return null;
} catch (Exception e) {
return e.toString() ;
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
}
finally
{
if ( tmp_file != null ) tmp_file.delete(); // just to be sure
}
}
} finally {
if (tmp_file != null) tmp_file.delete(); // just to be sure
} }
}
public boolean isCanceled() {
return BInstallerView.downloadCanceled; public boolean isCanceled() {
} return BInstallerView.downloadCanceled;
}
} }

View file

@ -18,118 +18,117 @@ import static android.content.Context.NOTIFICATION_SERVICE;
public class NotificationHelper { public class NotificationHelper {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
public static String BRouterNotificationChannel1 = "brouter_channel_01"; public static String BRouterNotificationChannel1 = "brouter_channel_01";
private Context mContext; private Context mContext;
private int NOTIFICATION_ID = 111; private int NOTIFICATION_ID = 111;
private Notification mNotification; private Notification mNotification;
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
private PendingIntent mContentIntent; private PendingIntent mContentIntent;
private CharSequence mContentTitle; private CharSequence mContentTitle;
public NotificationHelper(Context context) public NotificationHelper(Context context) {
{ if (DEBUG) Log.d("NH", "init ");
if (DEBUG) Log.d("NH", "init " ); mContext = context;
mContext = context; createNotificationChannels();
createNotificationChannels(); }
public void startNotification(Service service) {
if (DEBUG) Log.d("NH", "startNotification ");
mNotification = createNotification("BRouter Download", "Download some files");
if (service != null) service.startForeground(NOTIFICATION_ID, mNotification);
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
public void progressUpdate(String text) {
mNotification = createNotification("BRouter Download", text);
mNotification.flags = Notification.FLAG_NO_CLEAR |
Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
public Notification createNotification(String title, String desc) {
Intent resultIntent = new Intent(mContext, BInstallerActivity.class);
Intent notificationIntent = new Intent();
mContentIntent = PendingIntent.getActivity(mContext, 0, resultIntent, PendingIntent.FLAG_IMMUTABLE);
mNotificationManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, BRouterNotificationChannel1);
builder.setSmallIcon(android.R.drawable.stat_sys_download)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(title)
.setContentText(desc)
.setTicker(desc)
.setOngoing(true)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentIntent(mContentIntent);
return builder.build();
} else {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
builder.setSmallIcon(android.R.drawable.stat_sys_download)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(title)
.setContentText(desc)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentIntent(mContentIntent);
return builder.build();
} }
public void startNotification(Service service) { }
if (DEBUG) Log.d("NH", "startNotification " );
mNotification = createNotification("BRouter Download", "Download some files"); /**
* create notification channels
*/
public void createNotificationChannels() {
if (DEBUG) Log.d("NH", "createNotificationChannels ");
if (service != null) service.startForeground(NOTIFICATION_ID, mNotification); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mNotificationManager.notify(NOTIFICATION_ID, mNotification); NotificationManager sNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
// Sound channel
CharSequence name = "BRouter Download";
// The user-visible description of the channel.
String description = "BRouter Download Channel"; //getString(R.string.channel_description);
NotificationChannel channel = new NotificationChannel(BRouterNotificationChannel1, name, NotificationManager.IMPORTANCE_LOW);
channel.setDescription(description);
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_UNKNOWN)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.build();
channel.setSound(null, null);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
sNotificationManager.createNotificationChannel(channel);
} }
}
public void progressUpdate(String text) { public void stopNotification() {
mNotification = createNotification("BRouter Download", text); if (DEBUG) Log.d("NH", "stopNotification ");
mNotification.flags = Notification.FLAG_NO_CLEAR | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.FLAG_ONGOING_EVENT; mNotificationManager.deleteNotificationChannel(BRouterNotificationChannel1);
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
public Notification createNotification(String title, String desc) {
Intent resultIntent = new Intent(mContext, BInstallerActivity.class);
Intent notificationIntent = new Intent();
mContentIntent = PendingIntent.getActivity(mContext, 0, resultIntent, PendingIntent.FLAG_IMMUTABLE);
mNotificationManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, BRouterNotificationChannel1);
builder.setSmallIcon(android.R.drawable.stat_sys_download)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(title)
.setContentText(desc)
.setTicker(desc)
.setOngoing(true)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentIntent(mContentIntent);
return builder.build();
} else {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
builder.setSmallIcon(android.R.drawable.stat_sys_download)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(title)
.setContentText(desc)
.setOnlyAlertOnce(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentIntent(mContentIntent);
return builder.build();
}
}
/**
* create notification channels
*/
public void createNotificationChannels() {
if (DEBUG) Log.d("NH", "createNotificationChannels " );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager sNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
// Sound channel
CharSequence name = "BRouter Download";
// The user-visible description of the channel.
String description = "BRouter Download Channel"; //getString(R.string.channel_description);
NotificationChannel channel = new NotificationChannel(BRouterNotificationChannel1, name, NotificationManager.IMPORTANCE_LOW);
channel.setDescription(description);
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_UNKNOWN)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.build();
channel.setSound(null, null);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
sNotificationManager.createNotificationChannel(channel);
}
}
public void stopNotification() {
if (DEBUG) Log.d("NH", "stopNotification " );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mNotificationManager.deleteNotificationChannel(BRouterNotificationChannel1);
}
mNotificationManager.cancel(NOTIFICATION_ID);
} }
mNotificationManager.cancel(NOTIFICATION_ID);
}
} }

View file

@ -7,44 +7,38 @@ import java.util.TreeSet;
/** /**
* Decsription of a service config * Decsription of a service config
*/ */
public class ServiceModeConfig public class ServiceModeConfig {
{
public String mode; public String mode;
public String profile; public String profile;
public TreeSet<String> nogoVetos; public TreeSet<String> nogoVetos;
public ServiceModeConfig( String line ) public ServiceModeConfig(String line) {
{ StringTokenizer tk = new StringTokenizer(line);
StringTokenizer tk = new StringTokenizer( line );
mode = tk.nextToken(); mode = tk.nextToken();
profile = tk.nextToken(); profile = tk.nextToken();
nogoVetos = new TreeSet<String>(); nogoVetos = new TreeSet<String>();
while( tk.hasMoreTokens() ) while (tk.hasMoreTokens()) {
{ nogoVetos.add(tk.nextToken());
nogoVetos.add( tk.nextToken() );
} }
} }
public ServiceModeConfig( String mode, String profile ) public ServiceModeConfig(String mode, String profile) {
{
this.mode = mode; this.mode = mode;
this.profile = profile; this.profile = profile;
nogoVetos = new TreeSet<String>(); nogoVetos = new TreeSet<String>();
} }
public String toLine() public String toLine() {
{ StringBuilder sb = new StringBuilder(100);
StringBuilder sb = new StringBuilder( 100 ); sb.append(mode).append(' ').append(profile);
sb.append( mode ).append( ' ' ).append( profile ); for (String veto : nogoVetos) sb.append(' ').append(veto);
for( String veto: nogoVetos ) sb.append( ' ' ).append( veto );
return sb.toString(); return sb.toString();
} }
public String toString() public String toString() {
{ StringBuilder sb = new StringBuilder(100);
StringBuilder sb = new StringBuilder( 100 ); sb.append(mode).append("->").append(profile);
sb.append( mode ).append( "->" ).append( profile ); sb.append(" [" + nogoVetos.size() + "]");
sb.append ( " [" + nogoVetos.size() + "]" );
return sb.toString(); return sb.toString();
} }
} }

View file

@ -2,8 +2,7 @@ package btools.routingapp;
import java.io.File; import java.io.File;
public class WpDatabaseScanner extends Thread public class WpDatabaseScanner extends Thread {
{
private String currentDir = ""; private String currentDir = "";
private String bestGuess = ""; private String bestGuess = "";
private String lastError = ""; private String lastError = "";
@ -12,116 +11,87 @@ public class WpDatabaseScanner extends Thread
private long maxtimestamp = 0; private long maxtimestamp = 0;
public String getCurrentDir() public String getCurrentDir() {
{ synchronized (currentDirSync) {
synchronized (currentDirSync)
{
return currentDir; return currentDir;
} }
} }
private void setCurrentDir( String dir ) private void setCurrentDir(String dir) {
{ synchronized (currentDirSync) {
synchronized (currentDirSync)
{
currentDir = dir; currentDir = dir;
} }
} }
public String getBestGuess() public String getBestGuess() {
{ synchronized (currentDirSync) {
synchronized (currentDirSync)
{
return bestGuess; return bestGuess;
} }
} }
public String getLastError() public String getLastError() {
{ synchronized (currentDirSync) {
synchronized (currentDirSync)
{
return lastError; return lastError;
} }
} }
private void setLastError( String msg ) private void setLastError(String msg) {
{ synchronized (currentDirSync) {
synchronized (currentDirSync)
{
lastError = msg; lastError = msg;
} }
} }
private static String[] vetos = new String[] { "dev", "sys", "system", "proc", "etc", "init", "d", "cache", "acct", "data" }; private static String[] vetos = new String[]{"dev", "sys", "system", "proc", "etc", "init", "d", "cache", "acct", "data"};
private void scan( File dir, int level ) private void scan(File dir, int level) {
{ if (level > 8) {
if ( level > 8 )
{
return; return;
} }
try try {
{ if (dir.isDirectory()) {
if ( dir.isDirectory() ) if (level == 1) {
{
if ( level == 1 )
{
String name = dir.getName(); String name = dir.getName();
for( String veto: vetos ) for (String veto : vetos) {
{ if (veto.equals(name)) {
if ( veto.equals( name ) )
{
return; return;
} }
} }
} }
testPath( dir.getPath() ); testPath(dir.getPath());
File[] childs = dir.listFiles(); File[] childs = dir.listFiles();
if ( childs == null ) if (childs == null) {
{
return; return;
} }
for ( File child : childs ) for (File child : childs) {
{ scan(child, level + 1);
scan( child, level+1 );
} }
} }
} } catch (Exception e) {
catch (Exception e) setLastError(e.toString());
{
setLastError( e.toString() );
} }
} }
private void testPath( String path ) throws Exception private void testPath(String path) throws Exception {
{ setCurrentDir(path);
setCurrentDir( path );
testReader( new CoordinateReaderOsmAnd( path ) ); testReader(new CoordinateReaderOsmAnd(path));
testReader( new CoordinateReaderOsmAnd( path, true ) ); testReader(new CoordinateReaderOsmAnd(path, true));
testReader( new CoordinateReaderLocus( path ) ); testReader(new CoordinateReaderLocus(path));
testReader( new CoordinateReaderOrux( path ) ); testReader(new CoordinateReaderOrux(path));
} }
private void testReader( CoordinateReader cor ) throws Exception private void testReader(CoordinateReader cor) throws Exception {
{
long ts = cor.getTimeStamp(); long ts = cor.getTimeStamp();
if ( ts > maxtimestamp ) if (ts > maxtimestamp) {
{
maxtimestamp = ts; maxtimestamp = ts;
synchronized (currentDirSync) synchronized (currentDirSync) {
{
bestGuess = cor.basedir; bestGuess = cor.basedir;
} }
} } else if (ts > 0 && ts == maxtimestamp) {
else if ( ts > 0 && ts == maxtimestamp ) synchronized (currentDirSync) {
{ if (cor.basedir.length() < bestGuess.length()) {
synchronized (currentDirSync)
{
if ( cor.basedir.length() < bestGuess.length() )
{
bestGuess = cor.basedir; bestGuess = cor.basedir;
} }
} }
@ -129,10 +99,9 @@ public class WpDatabaseScanner extends Thread
} }
@Override @Override
public void run() public void run() {
{ scan(new File("/"), 0);
scan( new File( "/" ), 0 ); setCurrentDir(null);
setCurrentDir( null );
} }
} }