1.3.2 preparations

This commit is contained in:
Arndt 2015-11-01 09:34:43 +01:00
parent 14a18fd770
commit 3e50846135
17 changed files with 1929 additions and 1906 deletions

View file

@ -268,7 +268,7 @@ public final class OsmTrack
sb.append( " xmlns=\"http://www.topografix.com/GPX/1/1\" \n" ); sb.append( " xmlns=\"http://www.topografix.com/GPX/1/1\" \n" );
sb.append( " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" ); sb.append( " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" );
sb.append( " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n" ); sb.append( " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n" );
sb.append( " creator=\"BRouter-1.3.1\" version=\"1.1\">\n" ); sb.append( " creator=\"BRouter-1.3.2\" version=\"1.1\">\n" );
sb.append( " <trk>\n" ); sb.append( " <trk>\n" );
sb.append( " <name>" ).append( name ).append( "</name>\n" ); sb.append( " <name>" ).append( name ).append( "</name>\n" );
sb.append( " <trkseg>\n" ); sb.append( " <trkseg>\n" );

View file

@ -236,7 +236,12 @@ public class RoutingEngine extends Thread
{ {
try try
{ {
MatchedWaypoint seedPoint = matchNodeForPosition( waypoints.get(0) ); MatchedWaypoint seedPoint = new MatchedWaypoint();
seedPoint.waypoint = waypoints.get(0);
List<MatchedWaypoint> listOne = new ArrayList<MatchedWaypoint>();
listOne.add( seedPoint );
matchWaypointsToNodes( listOne );
routingContext.countTraffic = true; routingContext.countTraffic = true;
findTrack( "seededSearch", seedPoint, null, null, null, false ); findTrack( "seededSearch", seedPoint, null, null, null, false );

View file

@ -577,6 +577,10 @@ public abstract class BExpressionContext
public void parseFile( File file, String readOnlyContext ) public void parseFile( File file, String readOnlyContext )
{ {
if ( !file.exists() )
{
throw new IllegalArgumentException( "profile " + file + " does not exist" );
}
try try
{ {
if ( readOnlyContext != null ) if ( readOnlyContext != null )

View file

@ -17,57 +17,58 @@ public class TrafficData2Png
private static int nrows; private static int nrows;
private static int[] pixels; private static int[] pixels;
public static void main( String[] args) throws Exception public static void main( String[] args ) throws Exception
{ {
if ( args.length == 8 ) if ( args.length == 8 )
{ {
doConvert( args[0], args[1], doConvert( args[0], args[1], Double.parseDouble( args[2] ), Double.parseDouble( args[3] ), Double.parseDouble( args[4] ),
Double.parseDouble( args[2] ), Double.parseDouble( args[3] ), Double.parseDouble( args[4] ), Double.parseDouble( args[5] ), Double.parseDouble( args[5] ), Integer.parseInt( args[6] ), Integer.parseInt( args[7] ) );
Integer.parseInt( args[6] ), Integer.parseInt( args[7] ) );
} }
else if ( args.length == 4 ) else if ( args.length == 4 )
{ {
int lon0 = Integer.parseInt( args[0] ); int lon0 = Integer.parseInt( args[0] );
int lat0 = Integer.parseInt( args[1] ); int lat0 = Integer.parseInt( args[1] );
String inputFile = "traffic/E" + lon0 + "_N" + lat0 + ".trf"; String inputFile = "traffic/E" + lon0 + "_N" + lat0 + ".trf";
for( int lon = lon0; lon < lon0+5; lon++ ) for ( int lon = lon0; lon < lon0 + 5; lon++ )
for( int lat = lat0; lat < lat0+5; lat++ ) for ( int lat = lat0; lat < lat0 + 5; lat++ )
{ {
String imageFile = "traffic_pics/E" + lon + "_N" + lat + ".png"; String imageFile = "traffic_pics/E" + lon + "_N" + lat + ".png";
System.out.println( "file=" + inputFile + " image=" + imageFile ); System.out.println( "file=" + inputFile + " image=" + imageFile );
doConvert( inputFile, imageFile, lon, lat, lon+1, lat+1, Integer.parseInt( args[2] ), Integer.parseInt( args[3] ) ); doConvert( inputFile, imageFile, lon, lat, lon + 1, lat + 1, Integer.parseInt( args[2] ), Integer.parseInt( args[3] ) );
} }
} }
} }
public static void doConvert( String inputFile, String imageFile, double lon0, double lat0, double lon1, double lat1, public static void doConvert( String inputFile, String imageFile, double lon0, double lat0, double lon1, double lat1, int cols, int rows )
int cols, int rows ) throws Exception throws Exception
{ {
OsmTrafficMap trafficMap = new OsmTrafficMap(); OsmTrafficMap trafficMap = new OsmTrafficMap();
minLon = (int)(lon0 * 1000000 + 180000000); minLon = (int) ( lon0 * 1000000 + 180000000 );
maxLon = (int)(lon1 * 1000000 + 180000000); maxLon = (int) ( lon1 * 1000000 + 180000000 );
minLat = (int)(lat0 * 1000000 + 90000000); minLat = (int) ( lat0 * 1000000 + 90000000 );
maxLat = (int)(lat1 * 1000000 + 90000000); maxLat = (int) ( lat1 * 1000000 + 90000000 );
ncols = cols; ncols = cols;
nrows = rows; nrows = rows;
long[] keys = trafficMap.load( new File( inputFile ), minLon, minLat, maxLon, maxLat, true ); long[] keys = trafficMap.load( new File( inputFile ), minLon, minLat, maxLon, maxLat, true );
pixels = new int[cols*rows]; pixels = new int[cols * rows];
int[] tclasses = new int[] { 1,2,3,4,5,6,7, -1 }; int[] tclasses = new int[]
for( int tclass : tclasses ) { 1, 2, 3, 4, 5, 6, 7, -1 };
for ( int tclass : tclasses )
{ {
for(long key : keys ) for ( long key : keys )
{ {
OsmTrafficMap.OsmTrafficElement e = trafficMap.getElement(key ); OsmTrafficMap.OsmTrafficElement e = trafficMap.getElement( key );
while( e != null ) while (e != null)
{ {
long key2 = e.node2; long key2 = e.node2;
e = e.next; e = e.next;
int trafficClass = trafficMap.getTrafficClass( key, key2 ); int trafficClass = trafficMap.getTrafficClass( key, key2 );
if ( trafficClass != tclass ) continue; if ( trafficClass != tclass )
continue;
int[] from = getImagePosition( key ); int[] from = getImagePosition( key );
int[] to = getImagePosition( key2 ); int[] to = getImagePosition( key2 );
@ -89,13 +90,11 @@ public class TrafficData2Png
} }
} }
byte[] png = new Raster2Png().pngEncode( cols, rows, pixels );
Raster2Png r2p = new Raster2Png( Raster2Png.FILTER_NONE, 6, cols, rows, pixels );
byte[] png = r2p.pngEncode( );
System.out.println( "got png of size: " + png.length ); System.out.println( "got png of size: " + png.length );
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( imageFile ) ) ); DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( imageFile ) ) );
dos.write(png); dos.write( png );
dos.close(); dos.close();
} }
@ -109,24 +108,25 @@ public class TrafficData2Png
int sx = ixx > ix ? 1 : -1; int sx = ixx > ix ? 1 : -1;
int sy = iyy > iy ? 1 : -1; int sy = iyy > iy ? 1 : -1;
int dx = (ixx-ix)*sx; int dx = ( ixx - ix ) * sx;
int dy = (iyy-iy)*sy; int dy = ( iyy - iy ) * sy;
int sum = 0; int sum = 0;
for(;;) for ( ;; )
{ {
drawPixel( ix, iy, rgb ); drawPixel( ix, iy, rgb );
if ( ix == ixx && iy == iyy ) break; if ( ix == ixx && iy == iyy )
break;
if ( Math.abs( sum+dx ) < Math.abs( sum-dy ) ) if ( Math.abs( sum + dx ) < Math.abs( sum - dy ) )
{ {
iy+= sy; iy += sy;
sum += dx; sum += dx;
} }
else else
{ {
ix+= sx; ix += sx;
sum -= dy; sum -= dy;
} }
} }
@ -136,19 +136,19 @@ public class TrafficData2Png
{ {
if ( ix >= 0 && ix < ncols && iy >= 0 && iy < nrows ) if ( ix >= 0 && ix < ncols && iy >= 0 && iy < nrows )
{ {
pixels[ (nrows-1-iy)*ncols + ix ] = rgb; pixels[( nrows - 1 - iy ) * ncols + ix] = rgb;
} }
} }
private static int[] getImagePosition( long key ) private static int[] getImagePosition( long key )
{ {
int ilon = (int)(key >> 32); int ilon = (int) ( key >> 32 );
int ilat = (int)(key & 0xffffffff); int ilat = (int) ( key & 0xffffffff );
double lonDelta = maxLon-minLon; double lonDelta = maxLon - minLon;
double latDelta = maxLat-minLat; double latDelta = maxLat - minLat;
int[] res = new int[2]; int[] res = new int[2];
res[0] = (int)( ( (ilon-minLon)/lonDelta ) *ncols ); res[0] = (int) ( ( ( ilon - minLon ) / lonDelta ) * ncols );
res[1] = (int)( ( (ilat-minLat)/latDelta ) *nrows ); res[1] = (int) ( ( ( ilat - minLat ) / latDelta ) * nrows );
return res; return res;
} }
} }

View file

@ -28,26 +28,33 @@ public class StorageConfigHelper
String configFile = segmentDir + "/storageconfig.txt"; String configFile = segmentDir + "/storageconfig.txt";
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;
line = line.trim(); line = line.trim();
if ( line.startsWith( "#") ) continue; if ( line.startsWith( "#" ) ) continue;
if ( line.startsWith( tag ) ) if ( line.startsWith( tag ) )
{ {
String path = line.substring( tag.length() ).trim(); String path = line.substring( tag.length() ).trim();
res = path.startsWith( "/" ) ? new File( path ) : new File( new File( segmentDir ) , path ); res = path.startsWith( "/" ) ? new File( path ) : new File( new File( segmentDir ), path );
if ( !res.exists() ) res = null; if ( !res.exists() ) res = null;
break; break;
} }
} }
} }
catch( Exception e ) {} catch (Exception e) { /* ignore */ }
finally finally
{ {
if ( br != null ) try { br.close(); } catch( Exception ee ) {} if ( br != null )
{
try
{
br.close();
}
catch (Exception ee) { /* ignore */ }
}
} }
return res; return res;
} }

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="8" android:versionCode="9"
android:versionName="1.3.1" package="btools.routingapp"> android:versionName="1.3.2" package="btools.routingapp">
<application android:icon="@drawable/icon" android:label="@string/app_name"> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".BRouterActivity" <activity android:name=".BRouterActivity"
android:label="@string/app_name" android:label="@string/app_name"

View file

@ -21,8 +21,8 @@ import android.speech.tts.TextToSpeech.OnInitListener;
import android.widget.EditText; import android.widget.EditText;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
public class BRouterActivity extends Activity implements OnInitListener { public class BRouterActivity extends Activity implements OnInitListener
{
private static final int DIALOG_SELECTPROFILE_ID = 1; private static final int DIALOG_SELECTPROFILE_ID = 1;
private static final int DIALOG_EXCEPTION_ID = 2; private static final int DIALOG_EXCEPTION_ID = 2;
private static final int DIALOG_SHOW_DM_INFO_ID = 3; private static final int DIALOG_SHOW_DM_INFO_ID = 3;
@ -44,248 +44,277 @@ public class BRouterActivity extends Activity implements OnInitListener {
/** 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() mWakeLock = mPowerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName() );
.getName());
// 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); mBRouterView = new BRouterView( this );
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;
switch(id) switch ( id )
{ {
case DIALOG_SELECTPROFILE_ID: case DIALOG_SELECTPROFILE_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
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) { {
public void onClick( DialogInterface dialog, int item )
{
selectedProfile = availableProfiles[item]; selectedProfile = availableProfiles[item];
mBRouterView.startProcessing(selectedProfile); mBRouterView.startProcessing( selectedProfile );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_MAINACTION_ID: case DIALOG_MAINACTION_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle("Select Main Action"); builder.setTitle( "Select Main Action" );
builder.setItems( new String[] { "Download Manager", "BRouter App" }, new DialogInterface.OnClickListener() { builder.setItems( new String[]
public void onClick(DialogInterface dialog, int item) { { "Download Manager", "BRouter App" }, new DialogInterface.OnClickListener()
if ( item == 0 ) startDownloadManager(); {
else showDialog( DIALOG_SELECTPROFILE_ID ); public void onClick( DialogInterface dialog, int item )
{
if ( item == 0 )
startDownloadManager();
else
showDialog( DIALOG_SELECTPROFILE_ID );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_SHOW_DM_INFO_ID: case DIALOG_SHOW_DM_INFO_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( "BRouter Download Manager" ) builder
.setMessage( "*** Attention: ***\n\n" .setTitle( "BRouter Download Manager" )
+ "The Download Manager is used to download routing-data " .setMessage(
+ "files which can be up to 100MB each. Do not start the Download Manager " "*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
+ "on a cellular data connection without a data plan! " + "files which can be up to 100MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! "
+ "Download speed is restricted to 2 MBit/s." ) + "Download speed is restricted to 2 MBit/s." ).setPositiveButton( "I know", new DialogInterface.OnClickListener()
.setPositiveButton( "I know", new DialogInterface.OnClickListener() { {
public void onClick(DialogInterface dialog, int id) { public void onClick( DialogInterface dialog, int id )
Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class); {
startActivity(intent); Intent intent = new Intent( BRouterActivity.this, BInstallerActivity.class );
startActivity( intent );
finish(); finish();
} }
}) } ).setNegativeButton( "Cancel", new DialogInterface.OnClickListener()
.setNegativeButton( "Cancel", new DialogInterface.OnClickListener() { {
public void onClick(DialogInterface dialog, int id) { public void onClick( DialogInterface dialog, int id )
{
finish(); finish();
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_OLDDATAHINT_ID: case DIALOG_OLDDATAHINT_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( "Local setup needs reset" ) builder
.setMessage( "You are currently using an old version of the lookup-table " .setTitle( "Local setup needs reset" )
+ "together with routing data made for this old table. " .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, " + "Before downloading new datafiles made for the new table, "
+ "you have to reset your local setup by 'moving away' (or deleting) " + "you have to reset your local setup by 'moving away' (or deleting) "
+ "your <basedir>/brouter directory and start a new setup by calling the " + "your <basedir>/brouter directory and start a new setup by calling the " + "BRouter App again." )
+ "BRouter App again." ) .setPositiveButton( "OK", new DialogInterface.OnClickListener()
.setPositiveButton( "OK", new DialogInterface.OnClickListener() { {
public void onClick(DialogInterface dialog, int id) { public void onClick( DialogInterface dialog, int id )
{
finish(); finish();
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_ROUTINGMODES_ID: case DIALOG_ROUTINGMODES_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( message ); builder.setTitle( message );
builder.setMultiChoiceItems(routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener() { builder.setMultiChoiceItems( routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener()
{
@Override @Override
public void onClick(DialogInterface dialog, int which, public void onClick( DialogInterface dialog, int which, boolean isChecked )
boolean isChecked) { {
routingModesChecked[which] = isChecked; routingModesChecked[which] = isChecked;
} }
}); } );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton) { {
mBRouterView.configureService(routingModes,routingModesChecked); public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.configureService( routingModes, routingModesChecked );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_EXCEPTION_ID: case DIALOG_EXCEPTION_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( "An Error occured" ) builder.setTitle( "An Error occured" ).setMessage( errorMessage ).setPositiveButton( "OK", new DialogInterface.OnClickListener()
.setMessage( errorMessage ) {
.setPositiveButton( "OK", new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int id )
public void onClick(DialogInterface dialog, int id) { {
mBRouterView.continueProcessing(); mBRouterView.continueProcessing();
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_TEXTENTRY_ID: case DIALOG_TEXTENTRY_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle("Enter SDCARD base dir:"); builder.setTitle( "Enter SDCARD base dir:" );
builder.setMessage(message); builder.setMessage( message );
final EditText input = new EditText(this); final EditText input = new EditText( this );
input.setText( defaultbasedir ); input.setText( defaultbasedir );
builder.setView(input); builder.setView( input );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton) { {
public void onClick( DialogInterface dialog, int whichButton )
{
String basedir = input.getText().toString(); String basedir = input.getText().toString();
mBRouterView.startSetup(basedir, true ); mBRouterView.startSetup( basedir, true );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_SELECTBASEDIR_ID: case DIALOG_SELECTBASEDIR_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle("Select an SDCARD base dir:"); builder.setTitle( "Select an SDCARD base dir:" );
builder.setSingleChoiceItems(basedirOptions, 0, new DialogInterface.OnClickListener() { builder.setSingleChoiceItems( basedirOptions, 0, new DialogInterface.OnClickListener()
{
@Override @Override
public void onClick(DialogInterface dialog, int item ) public void onClick( DialogInterface dialog, int item )
{ {
selectedBasedir = item; selectedBasedir = item;
} }
}); } );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton) {
public void onClick( DialogInterface dialog, int whichButton )
{ {
if ( selectedBasedir < availableBasedirs.size() ) if ( selectedBasedir < availableBasedirs.size() )
{ {
mBRouterView.startSetup(availableBasedirs.get(selectedBasedir), true ); mBRouterView.startSetup( availableBasedirs.get( selectedBasedir ), true );
} }
else else
{ {
showDialog( DIALOG_TEXTENTRY_ID ); showDialog( DIALOG_TEXTENTRY_ID );
} }
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_VIASELECT_ID: case DIALOG_VIASELECT_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle("Check VIA Selection:"); builder.setTitle( "Check VIA Selection:" );
builder.setMultiChoiceItems(availableVias, getCheckedBooleanArray( availableVias.length ), builder.setMultiChoiceItems( availableVias, getCheckedBooleanArray( availableVias.length ), new DialogInterface.OnMultiChoiceClickListener()
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if (isChecked)
{ {
selectedVias.add(availableVias[which]); @Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
if ( isChecked )
{
selectedVias.add( availableVias[which] );
} }
else else
{ {
selectedVias.remove(availableVias[which]); selectedVias.remove( availableVias[which] );
} }
} }
}); } );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton) { {
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateViaList( selectedVias ); mBRouterView.updateViaList( selectedVias );
mBRouterView.startProcessing(selectedProfile); mBRouterView.startProcessing( selectedProfile );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_NOGOSELECT_ID: case DIALOG_NOGOSELECT_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle("Check NoGo Selection:"); builder.setTitle( "Check NoGo Selection:" );
String[] nogoNames = new String[nogoList.size()]; String[] nogoNames = new String[nogoList.size()];
for( int i=0; i<nogoList.size(); i++ ) nogoNames[i] = nogoList.get(i).name; for ( int i = 0; i < nogoList.size(); i++ )
final boolean[] nogoEnabled = getCheckedBooleanArray(nogoList.size()); nogoNames[i] = nogoList.get( i ).name;
builder.setMultiChoiceItems(nogoNames, getCheckedBooleanArray( nogoNames.length ), final boolean[] nogoEnabled = getCheckedBooleanArray( nogoList.size() );
new DialogInterface.OnMultiChoiceClickListener() { builder.setMultiChoiceItems( nogoNames, getCheckedBooleanArray( nogoNames.length ), new DialogInterface.OnMultiChoiceClickListener()
{
@Override @Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) { public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
nogoEnabled[which] = isChecked; nogoEnabled[which] = isChecked;
} }
}); } );
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton) { {
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateNogoList( nogoEnabled ); mBRouterView.updateNogoList( nogoEnabled );
mBRouterView.startProcessing(selectedProfile); mBRouterView.startProcessing( selectedProfile );
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_SHOWRESULT_ID: case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? "Exit" : ( wpCount == 0 ? "Select from" : "Select to/via" ); String leftLabel = wpCount < 0 ? "Exit" : ( wpCount == 0 ? "Select from" : "Select to/via" );
String rightLabel = wpCount < 2 ? "Server-Mode" : "Calc Route"; String rightLabel = wpCount < 2 ? "Server-Mode" : "Calc Route";
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( title ) builder.setTitle( title ).setMessage( errorMessage ).setPositiveButton( leftLabel, new DialogInterface.OnClickListener()
.setMessage( errorMessage ) {
.setPositiveButton( leftLabel, new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int id )
public void onClick(DialogInterface dialog, int id) { {
if ( wpCount < 0 ) finish(); if ( wpCount < 0 )
else mBRouterView.pickWaypoints(); finish();
else
mBRouterView.pickWaypoints();
} }
}) } ).setNegativeButton( rightLabel, new DialogInterface.OnClickListener()
.setNegativeButton( rightLabel, new DialogInterface.OnClickListener() { {
public void onClick(DialogInterface dialog, int id) { public void onClick( DialogInterface dialog, int id )
if ( wpCount < 2 ) mBRouterView.startConfigureService(); {
if ( wpCount < 2 )
mBRouterView.startConfigureService();
else else
{ {
mBRouterView.finishWaypointSelection(); mBRouterView.finishWaypointSelection();
mBRouterView.startProcessing(selectedProfile); mBRouterView.startProcessing( selectedProfile );
} }
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_MODECONFIGOVERVIEW_ID: case DIALOG_MODECONFIGOVERVIEW_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( "Success" ) builder.setTitle( "Success" ).setMessage( message ).setPositiveButton( "Exit", new DialogInterface.OnClickListener()
.setMessage( message ) {
.setPositiveButton( "Exit", new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int id )
public void onClick(DialogInterface dialog, int id) { {
finish(); finish();
} }
}); } );
return builder.create(); return builder.create();
case DIALOG_PICKWAYPOINT_ID: case DIALOG_PICKWAYPOINT_ID:
builder = new AlertDialog.Builder(this); builder = new AlertDialog.Builder( this );
builder.setTitle( wpCount > 0 ? "Select to/via" : "Select from" ); builder.setTitle( wpCount > 0 ? "Select to/via" : "Select from" );
builder.setItems(availableWaypoints, new DialogInterface.OnClickListener() { builder.setItems( availableWaypoints, new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int item) { {
public void onClick( DialogInterface dialog, int item )
{
mBRouterView.updateWaypointList( availableWaypoints[item] ); mBRouterView.updateWaypointList( availableWaypoints[item] );
mBRouterView.startProcessing(selectedProfile); mBRouterView.startProcessing( selectedProfile );
} }
}); } );
return builder.create(); return builder.create();
default: default:
return null; 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;
} }
@ -309,12 +338,11 @@ public class BRouterActivity extends Activity implements OnInitListener {
private List<OsmNodeNamed> nogoList; private List<OsmNodeNamed> nogoList;
public boolean isOnline() { public boolean isOnline()
ConnectivityManager cm = {
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE );
return cm.getActiveNetworkInfo() != null && return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting();
cm.getActiveNetworkInfo().isConnectedOrConnecting();
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -353,27 +381,27 @@ public class BRouterActivity extends Activity implements OnInitListener {
this.message = message; this.message = message;
availableBasedirs = new ArrayList<String>(); availableBasedirs = new ArrayList<String>();
ArrayList<Long> dirFreeSizes = new ArrayList<Long>(); ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
for( String d : items ) for ( String d : items )
{ {
try try
{ {
StatFs stat = new StatFs(d); StatFs stat = new StatFs( d );
long size = (long)stat.getAvailableBlocks()*stat.getBlockSize(); long size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
int idx = 0; int idx = 0;
while ( idx < availableBasedirs.size() && dirFreeSizes.get(idx).longValue() > size ) idx++; while (idx < availableBasedirs.size() && dirFreeSizes.get( idx ).longValue() > size)
idx++;
availableBasedirs.add( idx, d ); availableBasedirs.add( idx, d );
dirFreeSizes.add( idx, Long.valueOf( size ) ); dirFreeSizes.add( idx, Long.valueOf( size ) );
} }
catch( Exception e ) { /* ignore */ } catch (Exception e) { /* ignore */ }
} }
basedirOptions= new String[items.size() + 1]; basedirOptions = new String[items.size() + 1];
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) basedirOptions[bdidx++] = availableBasedirs.get( idx ) + " (" + df.format( dirFreeSizes.get( idx ) / 1024. / 1024. / 1024. ) + " GB free)";
+ " (" + df.format( dirFreeSizes.get(idx)/1024./1024./1024. ) + " GB free)";
} }
basedirOptions[bdidx] = "Other"; basedirOptions[bdidx] = "Other";
@ -396,13 +424,13 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 ) selectedVias.add( via ); for ( String via : items )
selectedVias.add( via );
showDialog( DIALOG_VIASELECT_ID ); showDialog( DIALOG_VIASELECT_ID );
} }
@ -453,41 +481,34 @@ public class BRouterActivity extends Activity implements OnInitListener {
} }
@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 * when the activity is resumed, we acquire a wake-lock so that the screen
* screen stays on, since the user will likely not be fiddling with the * stays on, since the user will likely not be fiddling with the screen or
* screen or buttons. * buttons.
*/ */
mWakeLock.acquire(); mWakeLock.acquire();
// Start the simulation
mBRouterView.startSimulation();
} }
@Override @Override
protected void onPause() { protected void onPause()
{
super.onPause(); super.onPause();
/* /*
* When the activity is paused, we make sure to stop the simulation, * When the activity is paused, we make sure to stop the router
* release our sensor resources and wake locks
*/ */
// Stop the simulation // Stop the simulation
mBRouterView.stopSimulation(); mBRouterView.stopRouting();
// and release our wake-lock // and release our wake-lock
mWakeLock.release(); mWakeLock.release();
} }
@Override @Override
public void onInit(int i) public void onInit( int i )
{ {
} }
} }

View file

@ -72,22 +72,22 @@ public class BRouterView extends View
private int[] imgPixels; private int[] imgPixels;
public void stopRouting()
public void startSimulation() { {
}
public void stopSimulation() {
if ( cr != null ) cr.terminate(); if ( cr != null ) cr.terminate();
} }
public BRouterView(Context context) { public BRouterView( Context context )
super(context); {
super( context );
} }
public void init() public void init()
{
try
{ {
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
((Activity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics); ( (Activity) getContext() ).getWindowManager().getDefaultDisplay().getMetrics( metrics );
imgw = metrics.widthPixels; imgw = metrics.widthPixels;
imgh = metrics.heightPixels; imgh = metrics.heightPixels;
@ -106,15 +106,22 @@ public class BRouterView extends View
return; return;
} }
} }
String message = baseDir == null ? String message = baseDir == null ? "(no basedir configured previously)" : "(previous basedir " + baseDir
"(no basedir configured previously)" : + ( bdValid ? " does not contain 'brouter' subfolder)" : " is not valid)" );
"(previous basedir " + baseDir +
( bdValid ? " does not contain 'brouter' subfolder)"
: " is not valid)" );
((BRouterActivity)getContext()).selectBasedir( getStorageDirectories(), guessBaseDir(), message ); ( (BRouterActivity) getContext() ).selectBasedir( getStorageDirectories(), guessBaseDir(), message );
waitingForSelection = true; waitingForSelection = true;
} }
catch (Exception e)
{
String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString();
AppLogger.log( msg );
AppLogger.log( AppLogger.formatThrowable( e ) );
( (BRouterActivity) getContext() ).showErrorMessage( msg );
}
}
public void startSetup( String baseDir, boolean storeBasedir ) public void startSetup( String baseDir, boolean storeBasedir )
{ {
@ -130,14 +137,27 @@ public class BRouterView extends View
{ {
// Android 4.4 patch: try extend the basedir if not valid // Android 4.4 patch: try extend the basedir if not valid
File td = new File( fbd, "brouter" ); File td = new File( fbd, "brouter" );
try { td.mkdir(); } catch ( Exception e ) {}; try
{
td.mkdir();
}
catch (Exception e) {}
if ( !td.isDirectory() ) if ( !td.isDirectory() )
{ {
File td1 = new File( fbd, "Android/data/btools/routingapp" ); File td1 = new File( fbd, "Android/data/btools/routingapp" );
try { td1.mkdirs(); } catch ( Exception e ) {}; try
{
td1.mkdirs();
}
catch (Exception e){}
td = new File( td1, "brouter" ); td = new File( td1, "brouter" );
try { td.mkdir(); } catch ( Exception e ) {}; try
if ( td.isDirectory() ) fbd = td1; {
td.mkdir();
}
catch (Exception e) {}
if ( td.isDirectory() )
fbd = td1;
} }
ConfigHelper.writeBaseDir( getContext(), baseDir ); ConfigHelper.writeBaseDir( getContext(), baseDir );
@ -148,7 +168,12 @@ public class BRouterView extends View
// create missing directories // create missing directories
assertDirectoryExists( "project directory", basedir + "/brouter", null ); assertDirectoryExists( "project directory", basedir + "/brouter", null );
segmentDir = basedir + "/brouter/segments4"; segmentDir = basedir + "/brouter/segments4";
assertDirectoryExists( "data directory", segmentDir, "segments4.zip" ); if ( assertDirectoryExists( "data directory", segmentDir, "segments4.zip" ) )
{
ConfigMigration.tryMigrateStorageConfig(
new File( basedir + "/brouter/segments3/storageconfig.txt" ),
new File( basedir + "/brouter/segments4/storageconfig.txt" ) );
}
profileDir = basedir + "/brouter/profiles2"; profileDir = basedir + "/brouter/profiles2";
assertDirectoryExists( "profile directory", profileDir, "profiles2.zip" ); assertDirectoryExists( "profile directory", profileDir, "profiles2.zip" );
modesDir = basedir + "/brouter/modes"; modesDir = basedir + "/brouter/modes";
@ -176,9 +201,23 @@ public class BRouterView extends View
if ( tracksDirPointer.isFile() ) if ( tracksDirPointer.isFile() )
{ {
tracksDir = readSingleLineFile( tracksDirPointer ); tracksDir = readSingleLineFile( tracksDirPointer );
if ( tracksDir == null ) throw new IllegalArgumentException( "redirect pointer file is empty: " + tracksDirPointer ); if ( tracksDir == null )
if ( !(new File( tracksDir ).isDirectory()) ) throw new IllegalArgumentException( throw new IllegalArgumentException( "redirect pointer file is empty: " + tracksDirPointer );
"redirect pointer file " + tracksDirPointer + " does not point to a directory: " + tracksDir ); if ( !( new File( tracksDir ).isDirectory() ) )
throw new IllegalArgumentException( "redirect pointer file " + tracksDirPointer + " does not point to a directory: " + tracksDir );
}
else
{
File writeTest = new File( tracksDir + "/brouter.writetest" );
try
{
writeTest.createNewFile();
writeTest.delete();
}
catch( Exception e )
{
tracksDir = basedir + "/brouter";
}
} }
} }
@ -186,48 +225,47 @@ public class BRouterView extends View
ArrayList<String> profiles = new ArrayList<String>(); ArrayList<String> profiles = new ArrayList<String>();
boolean lookupsFound = false; boolean lookupsFound = false;
for( String fileName : fileNames ) for ( String fileName : fileNames )
{ {
if ( fileName.endsWith( ".brf" ) ) if ( fileName.endsWith( ".brf" ) )
{ {
profiles.add( fileName.substring( 0, fileName.length()-4 ) ); profiles.add( fileName.substring( 0, fileName.length() - 4 ) );
} }
if ( fileName.equals( "lookups.dat" ) ) lookupsFound = true; if ( fileName.equals( "lookups.dat" ) )
lookupsFound = true;
} }
if ( !lookupsFound ) if ( !lookupsFound )
{ {
throw new IllegalArgumentException( "The profile-directory " + profileDir throw new IllegalArgumentException( "The profile-directory " + profileDir + " does not contain the lookups.dat file."
+ " does not contain the lookups.dat file."
+ " see www.dr-brenschede.de/brouter for setup instructions." ); + " see www.dr-brenschede.de/brouter for setup instructions." );
} }
if ( profiles.size() == 0 ) if ( profiles.size() == 0 )
{ {
throw new IllegalArgumentException( "The profile-directory " + profileDir throw new IllegalArgumentException( "The profile-directory " + profileDir + " contains no routing profiles (*.brf)."
+ " contains no routing profiles (*.brf)."
+ " see www.dr-brenschede.de/brouter for setup instructions." ); + " see www.dr-brenschede.de/brouter for setup instructions." );
} }
if ( !RoutingHelper.hasDirectoryAnyDatafiles( segmentDir ) ) if ( !RoutingHelper.hasDirectoryAnyDatafiles( segmentDir ) )
{ {
((BRouterActivity)getContext()).startDownloadManager(); ( (BRouterActivity) getContext() ).startDownloadManager();
waitingForSelection = true; waitingForSelection = true;
return; return;
} }
((BRouterActivity)getContext()).selectProfile( profiles.toArray( new String[0]) ); ( (BRouterActivity) getContext() ).selectProfile( profiles.toArray( new String[0] ) );
} }
catch( Exception e ) catch (Exception e)
{ {
String msg = e instanceof IllegalArgumentException String msg = e instanceof IllegalArgumentException ? e.getMessage()
? e.getMessage() + ( cor == null ? "" : " (coordinate-source: " + cor.basedir + cor.rootdir + ")" ) + ( cor == null ? "" : " (coordinate-source: " + cor.basedir + cor.rootdir + ")" ) : e.toString();
: e.toString();
AppLogger.log( msg ); AppLogger.log( msg );
AppLogger.log( AppLogger.formatThrowable( e ) ); AppLogger.log( AppLogger.formatThrowable( e ) );
((BRouterActivity)getContext()).showErrorMessage( msg ); ( (BRouterActivity) getContext() ).showErrorMessage( msg );
} }
waitingForSelection = true; waitingForSelection = true;
} }
public boolean hasUpToDateLookups() public boolean hasUpToDateLookups()
{ {
BExpressionMetaData meta = new BExpressionMetaData(); BExpressionMetaData meta = new BExpressionMetaData();
@ -243,11 +281,11 @@ public class BRouterView extends View
public void updateViaList( Set<String> selectedVias ) public void updateViaList( Set<String> selectedVias )
{ {
ArrayList<OsmNodeNamed> filtered = new ArrayList<OsmNodeNamed>(wpList.size()); ArrayList<OsmNodeNamed> filtered = new ArrayList<OsmNodeNamed>( wpList.size() );
for( OsmNodeNamed n : wpList ) for ( OsmNodeNamed n : wpList )
{ {
String name = n.name; String name = n.name;
if ( "from".equals( name ) || "to".equals(name) || selectedVias.contains( name ) ) if ( "from".equals( name ) || "to".equals( name ) || selectedVias.contains( name ) )
filtered.add( n ); filtered.add( n );
} }
wpList = filtered; wpList = filtered;
@ -255,11 +293,11 @@ public class BRouterView extends View
public void updateNogoList( boolean[] enabled ) public void updateNogoList( boolean[] enabled )
{ {
for( int i=nogoList.size()-1; i >= 0; i-- ) for ( int i = nogoList.size() - 1; i >= 0; i-- )
{ {
if ( !enabled[i] ) if ( !enabled[i] )
{ {
nogoVetoList.add( nogoList.get(i) ); nogoVetoList.add( nogoList.get( i ) );
nogoList.remove( i ); nogoList.remove( i );
} }
} }
@ -269,34 +307,51 @@ public class BRouterView extends View
{ {
String msg = null; String msg = null;
Map<String,OsmNodeNamed> allpoints = cor.allpoints; if ( cor.allpoints == null )
if ( allpoints == null )
{ {
allpoints = new TreeMap<String,OsmNodeNamed>(); try
cor.allpoints = allpoints; {
try { cor.readFromTo(); } catch ( Exception e ) { msg = "Error reading waypoints: " + e.toString(); } cor.readAllPoints();
if ( allpoints.size() < 2 ) msg = "coordinate source does not contain enough waypoints: " + allpoints.size(); }
if ( allpoints.size() > 100 ) msg = "coordinate source contains too much waypoints: " + allpoints.size() + "(please use from/to/via names)"; catch (Exception e)
{
msg = "Error reading waypoints: " + e.toString();
}
int size = cor.allpoints.size();
if ( size < 1 )
msg = "coordinate source does not contain any waypoints!";
if ( size > 1000 )
msg = "coordinate source contains too much waypoints: " + size + "(please use from/to/via names)";
} }
if ( allpoints.size() < 1 ) msg = "no more wayoints available!";
if ( msg != null ) if ( msg != null )
{ {
((BRouterActivity)getContext()).showErrorMessage( msg ); ( (BRouterActivity) getContext() ).showErrorMessage( msg );
} }
else else
{ {
String[] wpts = new String[allpoints.size()]; String[] wpts = new String[cor.allpoints.size()];
int i = 0; int i = 0;
for( OsmNodeNamed wp : allpoints.values() ) wpts[i++] = wp.name; for ( OsmNodeNamed wp : cor.allpoints )
((BRouterActivity)getContext()).selectWaypoint( wpts ); wpts[i++] = wp.name;
( (BRouterActivity) getContext() ).selectWaypoint( wpts );
} }
} }
public void updateWaypointList( String waypoint ) public void updateWaypointList( String waypoint )
{ {
wpList.add( cor.allpoints.get( waypoint ) ); for( OsmNodeNamed wp : cor.allpoints )
cor.allpoints.remove( waypoint ); {
if ( wp.name.equals( waypoint ) )
{
if ( wp.ilat != 0 || wp.ilat != 0 )
{
wpList.add( wp );
}
return;
}
}
} }
public void finishWaypointSelection() public void finishWaypointSelection()
@ -312,17 +367,17 @@ public class BRouterView extends View
if ( needsViaSelection ) if ( needsViaSelection )
{ {
needsViaSelection = false; needsViaSelection = false;
String[] availableVias = new String[wpList.size()-2]; String[] availableVias = new String[wpList.size() - 2];
for( int viaidx=0; viaidx<wpList.size()-2; viaidx++ ) for ( int viaidx = 0; viaidx < wpList.size() - 2; viaidx++ )
availableVias[viaidx] = wpList.get( viaidx+1 ).name; availableVias[viaidx] = wpList.get( viaidx + 1 ).name;
((BRouterActivity)getContext()).selectVias( availableVias ); ( (BRouterActivity) getContext() ).selectVias( availableVias );
return; return;
} }
if ( needsNogoSelection ) if ( needsNogoSelection )
{ {
needsNogoSelection = false; needsNogoSelection = false;
((BRouterActivity)getContext()).selectNogos( nogoList ); ( (BRouterActivity) getContext() ).selectNogos( nogoList );
return; return;
} }
@ -336,9 +391,10 @@ public class BRouterView extends View
else else
{ {
msg = "current waypoint selection:\n"; msg = "current waypoint selection:\n";
for ( int i=0; i< wpList.size(); i++ ) msg += (i>0?"->" : "") + wpList.get(i).name; for ( int i = 0; i < wpList.size(); i++ )
msg += ( i > 0 ? "->" : "" ) + wpList.get( i ).name;
} }
((BRouterActivity)getContext()).showResultMessage( "Select Action", msg, wpList.size() ); ( (BRouterActivity) getContext() ).showResultMessage( "Select Action", msg, wpList.size() );
return; return;
} }
@ -348,9 +404,6 @@ public class BRouterView extends View
RoutingContext rc = new RoutingContext(); RoutingContext rc = new RoutingContext();
// TODO: TEST!
// rc.rawTrackPath = "/mnt/sdcard/brouter/modes/bicycle_fast_rawtrack.dat";
rc.localFunction = profilePath; rc.localFunction = profilePath;
int plain_distance = 0; int plain_distance = 0;
@ -360,7 +413,7 @@ public class BRouterView extends View
int minlat = Integer.MAX_VALUE; int minlat = Integer.MAX_VALUE;
OsmNode prev = null; OsmNode prev = null;
for( OsmNode n : wpList ) for ( OsmNode n : wpList )
{ {
maxlon = n.ilon > maxlon ? n.ilon : maxlon; maxlon = n.ilon > maxlon ? n.ilon : maxlon;
minlon = n.ilon < minlon ? n.ilon : minlon; minlon = n.ilon < minlon ? n.ilon : minlon;
@ -372,19 +425,21 @@ public class BRouterView extends View
} }
prev = n; prev = n;
} }
toast( "Plain distance = " + plain_distance/1000. + " km" ); toast( "Plain distance = " + plain_distance / 1000. + " km" );
centerLon = (maxlon + minlon)/2; centerLon = ( maxlon + minlon ) / 2;
centerLat = (maxlat + minlat)/2; centerLat = ( maxlat + minlat ) / 2;
double coslat = Math.cos( ((centerLat / 1000000.) - 90.) / 57.3 ) ; double coslat = Math.cos( ( ( centerLat / 1000000. ) - 90. ) / 57.3 );
double difflon = maxlon - minlon; double difflon = maxlon - minlon;
double difflat = maxlat - minlat; double difflat = maxlat - minlat;
scaleLon = imgw / (difflon*1.5); scaleLon = imgw / ( difflon * 1.5 );
scaleLat = imgh / (difflat*1.5); scaleLat = imgh / ( difflat * 1.5 );
if ( scaleLon < scaleLat*coslat ) scaleLat = scaleLon/coslat; if ( scaleLon < scaleLat * coslat )
else scaleLon = scaleLat*coslat; scaleLat = scaleLon / coslat;
else
scaleLon = scaleLat * coslat;
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
rc.prepareNogoPoints( nogoList ); rc.prepareNogoPoints( nogoList );
@ -395,15 +450,14 @@ public class BRouterView extends View
invalidate(); invalidate();
} }
catch( Exception e ) catch (Exception e)
{ {
String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString(); String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString();
toast( msg ); toast( msg );
} }
} }
private boolean assertDirectoryExists( String message, String path, String assetZip )
private void assertDirectoryExists( String message, String path, String assetZip )
{ {
File f = new File( path ); File f = new File( path );
if ( !f.exists() ) if ( !f.exists() )
@ -418,45 +472,50 @@ public class BRouterView extends View
InputStream is = assetManager.open( assetZip ); InputStream is = assetManager.open( assetZip );
ZipInputStream zis = new ZipInputStream( is ); ZipInputStream zis = new ZipInputStream( is );
byte[] data = new byte[1024]; byte[] data = new byte[1024];
for(;;) for ( ;; )
{ {
ZipEntry ze = zis.getNextEntry(); ZipEntry ze = zis.getNextEntry();
if ( ze == null ) break; if ( ze == null )
break;
String name = ze.getName(); String name = ze.getName();
FileOutputStream fos = new FileOutputStream( new File( f, name ) ); FileOutputStream fos = new FileOutputStream( new File( f, name ) );
for(;;) for ( ;; )
{ {
int len = zis.read( data, 0, 1024 ); int len = zis.read( data, 0, 1024 );
if ( len < 0 ) break; if ( len < 0 )
break;
fos.write( data, 0, len ); fos.write( data, 0, len );
} }
fos.close(); fos.close();
} }
is.close(); is.close();
return true;
} }
catch( IOException io ) catch (IOException io)
{ {
throw new RuntimeException( "error expanding " + assetZip + ": " + io ); throw new RuntimeException( "error expanding " + assetZip + ": " + io );
} }
} }
} }
if ( !f.exists() || !f.isDirectory() ) throw new IllegalArgumentException( message + ": " + path + " cannot be created" ); if ( !f.exists() || !f.isDirectory() )
throw new IllegalArgumentException( message + ": " + path + " cannot be created" );
return false;
} }
private void paintPosition( int ilon, int ilat, int color, int with ) private void paintPosition( int ilon, int ilat, int color, int with )
{ {
int lon = ilon - centerLon; int lon = ilon - centerLon;
int lat = ilat - centerLat; int lat = ilat - centerLat;
int x = imgw/2 + (int)(scaleLon*lon); int x = imgw / 2 + (int) ( scaleLon * lon );
int y = imgh/2 - (int)(scaleLat*lat); int y = imgh / 2 - (int) ( scaleLat * lat );
for( int nx=x-with; nx<=x+with; nx++) for ( int nx = x - with; nx <= x + with; nx++ )
for( int ny=y-with; ny<=y+with; ny++) for ( int ny = y - with; ny <= y + with; ny++ )
{ {
if ( nx >= 0 && nx < imgw && ny >= 0 && ny < imgh ) if ( nx >= 0 && nx < imgw && ny >= 0 && ny < imgh )
{ {
imgPixels[ nx+imgw*ny] = color; imgPixels[nx + imgw * ny] = color;
} }
} }
} }
@ -465,59 +524,76 @@ public class BRouterView extends View
{ {
int lon = n.ilon - centerLon; int lon = n.ilon - centerLon;
int lat = n.ilat - centerLat; int lat = n.ilat - centerLat;
int x = imgw/2 + (int)(scaleLon*lon); int x = imgw / 2 + (int) ( scaleLon * lon );
int y = imgh/2 - (int)(scaleLat*lat); int y = imgh / 2 - (int) ( scaleLat * lat );
int ir = (int)(n.radius * 1000000. * scaleLat); int ir = (int) ( n.radius * 1000000. * scaleLat );
if ( ir > minradius ) if ( ir > minradius )
{ {
Paint paint = new Paint(); Paint paint = new Paint();
paint.setColor( Color.RED ); paint.setColor( Color.RED );
paint.setStyle( Paint.Style.STROKE ); paint.setStyle( Paint.Style.STROKE );
canvas.drawCircle( (float)x, (float)y, (float)ir, paint ); canvas.drawCircle( (float) x, (float) y, (float) ir, paint );
} }
} }
@Override @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged( int w, int h, int oldw, int oldh )
{
} }
private void toast( String msg ) private void toast( String msg )
{ {
Toast.makeText(getContext(), msg, Toast.LENGTH_LONG ).show(); Toast.makeText( getContext(), msg, Toast.LENGTH_LONG ).show();
lastDataTime += 4000; // give time for the toast before exiting lastDataTime += 4000; // give time for the toast before exiting
} }
private long lastTs = System.currentTimeMillis();
private long lastTs = System.currentTimeMillis(); private long startTime = 0L;
private long startTime = 0L;
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw( Canvas canvas )
{
try try
{ {
_onDraw( canvas ); _onDraw( canvas );
} }
catch( Throwable t ) catch (Throwable t)
{ {
// on out of mem, try to stop the show // on out of mem, try to stop the show
if ( cr != null ) cr.cleanOnOOM(); if ( cr != null )
cr.cleanOnOOM();
cr = null; cr = null;
try { Thread.sleep( 2000 ); } catch( InterruptedException ie ) {} try
((BRouterActivity)getContext()).showErrorMessage( t.toString() ); {
Thread.sleep( 2000 );
}
catch (InterruptedException ie)
{
}
( (BRouterActivity) getContext() ).showErrorMessage( t.toString() );
waitingForSelection = true; waitingForSelection = true;
} }
} }
private void _onDraw(Canvas canvas) { private void _onDraw( Canvas canvas )
{
if ( waitingForSelection ) return; if ( waitingForSelection )
return;
long currentTs = System.currentTimeMillis(); long currentTs = System.currentTimeMillis();
long diffTs = currentTs - lastTs; long diffTs = currentTs - lastTs;
long sleeptime = 500 - diffTs; long sleeptime = 500 - diffTs;
while ( sleeptime < 200 ) sleeptime += 500; while (sleeptime < 200)
sleeptime += 500;
try { Thread.sleep( sleeptime ); } catch ( InterruptedException ie ) {} try
{
Thread.sleep( sleeptime );
}
catch (InterruptedException ie)
{
}
lastTs = System.currentTimeMillis(); lastTs = System.currentTimeMillis();
if ( cr == null || cr.isFinished() ) if ( cr == null || cr.isFinished() )
@ -526,24 +602,23 @@ private long startTime = 0L;
{ {
if ( cr.getErrorMessage() != null ) if ( cr.getErrorMessage() != null )
{ {
((BRouterActivity)getContext()).showErrorMessage( cr.getErrorMessage() ); ( (BRouterActivity) getContext() ).showErrorMessage( cr.getErrorMessage() );
cr = null; cr = null;
waitingForSelection = true; waitingForSelection = true;
return; return;
} }
else else
{ {
String result = "version = BRouter-1.3.1\n" String result = "version = BRouter-1.3.2\n" + "distance = " + cr.getDistance() / 1000. + " km\n" + "filtered ascend = " + cr.getAscend()
+ "distance = " + cr.getDistance()/1000. + " km\n" + " m\n" + "plain ascend = " + cr.getPlainAscend();
+ "filtered ascend = " + cr.getAscend() + " m\n"
+ "plain ascend = " + cr.getPlainAscend();
rawTrack = cr.getFoundRawTrack(); rawTrack = cr.getFoundRawTrack();
String title = "Success"; String title = "Success";
if ( cr.getAlternativeIndex() > 0 ) title += " / " + cr.getAlternativeIndex() + ". Alternative"; if ( cr.getAlternativeIndex() > 0 )
title += " / " + cr.getAlternativeIndex() + ". Alternative";
((BRouterActivity)getContext()).showResultMessage( title, result, -1 ); ( (BRouterActivity) getContext() ).showResultMessage( title, result, -1 );
cr = null; cr = null;
waitingForSelection = true; waitingForSelection = true;
return; return;
@ -551,56 +626,55 @@ private long startTime = 0L;
} }
else if ( System.currentTimeMillis() > lastDataTime ) else if ( System.currentTimeMillis() > lastDataTime )
{ {
System.exit(0); System.exit( 0 );
} }
} }
else else
{ {
lastDataTime = System.currentTimeMillis(); lastDataTime = System.currentTimeMillis();
imgPixels = new int[imgw*imgh]; imgPixels = new int[imgw * imgh];
int[] openSet = cr.getOpenSet(); int[] openSet = cr.getOpenSet();
for( int si = 0; si < openSet.length; si += 2 ) for ( int si = 0; si < openSet.length; si += 2 )
{ {
paintPosition( openSet[si], openSet[si+1], 0xffffff, 1 ); paintPosition( openSet[si], openSet[si + 1], 0xffffff, 1 );
} }
// paint nogos on top (red) // paint nogos on top (red)
for( int ngi=0; ngi<nogoList.size(); ngi++ ) for ( int ngi = 0; ngi < nogoList.size(); ngi++ )
{ {
OsmNodeNamed n = nogoList.get(ngi); OsmNodeNamed n = nogoList.get( ngi );
int color = 0xff0000; int color = 0xff0000;
paintPosition( n.ilon, n.ilat, color, 4 ); paintPosition( n.ilon, n.ilat, color, 4 );
} }
// paint start/end/vias on top (yellow/green/blue) // paint start/end/vias on top (yellow/green/blue)
for( int wpi=0; wpi<wpList.size(); wpi++ ) for ( int wpi = 0; wpi < wpList.size(); wpi++ )
{ {
OsmNodeNamed n = wpList.get(wpi); OsmNodeNamed n = wpList.get( wpi );
int color = wpi == 0 ? 0xffff00 : wpi < wpList.size()-1 ? 0xff : 0xff00; int color = wpi == 0 ? 0xffff00 : wpi < wpList.size() - 1 ? 0xff : 0xff00;
paintPosition( n.ilon, n.ilat, color, 4 ); paintPosition( n.ilon, n.ilat, color, 4 );
} }
canvas.drawBitmap(imgPixels, 0, imgw, (float)0., (float)0., imgw, imgh, false, null); canvas.drawBitmap( imgPixels, 0, imgw, (float) 0., (float) 0., imgw, imgh, false, null );
// nogo circles if any // nogo circles if any
for( int ngi=0; ngi<nogoList.size(); ngi++ ) for ( int ngi = 0; ngi < nogoList.size(); ngi++ )
{ {
OsmNodeNamed n = nogoList.get(ngi); OsmNodeNamed n = nogoList.get( ngi );
int color = 0xff0000; int color = 0xff0000;
paintCircle( canvas, n, color, 4 ); paintCircle( canvas, n, color, 4 );
} }
Paint paint = new Paint(); Paint paint = new Paint();
paint.setColor(Color.WHITE); paint.setColor( Color.WHITE );
paint.setTextSize(20); paint.setTextSize( 20 );
long mseconds = System.currentTimeMillis() - startTime; long mseconds = System.currentTimeMillis() - startTime;
long links = cr.getLinksProcessed(); long links = cr.getLinksProcessed();
long perS = (1000*links)/mseconds; long perS = ( 1000 * links ) / mseconds;
String msg = "Links: " + cr.getLinksProcessed() + " in " + (mseconds/1000) + "s (" + perS + " l/s)"; String msg = "Links: " + cr.getLinksProcessed() + " in " + ( mseconds / 1000 ) + "s (" + perS + " l/s)";
canvas.drawText( msg, 10, 25, paint); canvas.drawText( msg, 10, 25, paint );
} }
// and make sure to redraw asap // and make sure to redraw asap
invalidate(); invalidate();
@ -622,15 +696,15 @@ private long startTime = 0L;
} }
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>(); ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
for( String bdg : basedirGuesses ) for ( String bdg : basedirGuesses )
{ {
rl.add( new CoordinateReaderOsmAnd(bdg) ); rl.add( new CoordinateReaderOsmAnd( bdg ) );
rl.add( new CoordinateReaderLocus(bdg) ); rl.add( new CoordinateReaderLocus( bdg ) );
rl.add( new CoordinateReaderOrux(bdg) ); rl.add( new CoordinateReaderOrux( bdg ) );
} }
long tmax = 0; long tmax = 0;
CoordinateReader cor = null; CoordinateReader cor = null;
for( CoordinateReader r : rl ) for ( CoordinateReader r : rl )
{ {
long t = r.getTimeStamp(); long t = r.getTimeStamp();
if ( t > tmax ) if ( t > tmax )
@ -644,7 +718,7 @@ private long startTime = 0L;
return cor.basedir; return cor.basedir;
} }
} }
catch( Exception e ) catch (Exception e)
{ {
System.out.println( "guessBaseDir:" + e ); System.out.println( "guessBaseDir:" + e );
} }
@ -661,7 +735,9 @@ private long startTime = 0L;
{ {
rawTrack.writeBinary( rawTrackPath ); rawTrack.writeBinary( rawTrackPath );
} }
catch( Exception e ) {} catch (Exception e)
{
}
} }
else else
{ {
@ -671,11 +747,8 @@ private long startTime = 0L;
public void startConfigureService() public void startConfigureService()
{ {
String[] modes = new String[] { String[] modes = new String[]
"foot_short", "foot_fast", { "foot_short", "foot_fast", "bicycle_short", "bicycle_fast", "motorcar_short", "motorcar_fast" };
"bicycle_short", "bicycle_fast",
"motorcar_short", "motorcar_fast"
};
boolean[] modesChecked = new boolean[6]; boolean[] modesChecked = new boolean[6];
// parse global section of profile for mode preselection // parse global section of profile for mode preselection
@ -690,56 +763,66 @@ private long startTime = 0L;
if ( isFoot || isBike || isCar ) if ( isFoot || isBike || isCar )
{ {
modesChecked[ 0 ] = isFoot; modesChecked[0] = isFoot;
modesChecked[ 1 ] = isFoot; modesChecked[1] = isFoot;
modesChecked[ 2 ] = isBike; modesChecked[2] = isBike;
modesChecked[ 3 ] = isBike; modesChecked[3] = isBike;
modesChecked[ 4 ] = isCar; modesChecked[4] = isCar;
modesChecked[ 5 ] = isCar; modesChecked[5] = isCar;
} }
else else
{ {
for( int i=0; i<6; i++) for ( int i = 0; i < 6; i++ )
{ {
modesChecked[i] = true; modesChecked[i] = true;
} }
} }
String msg = "Choose service-modes to configure (" + profileName + " [" + nogoVetoList.size() + "])"; String msg = "Choose service-modes to configure (" + profileName + " [" + nogoVetoList.size() + "])";
((BRouterActivity)getContext()).selectRoutingModes( modes, modesChecked, msg ); ( (BRouterActivity) getContext() ).selectRoutingModes( modes, modesChecked, msg );
} }
public void configureService(String[] routingModes, boolean[] checkedModes) public void configureService( String[] routingModes, boolean[] checkedModes )
{ {
// read in current config // read in current config
TreeMap<String,ServiceModeConfig> map = new TreeMap<String,ServiceModeConfig>(); TreeMap<String, ServiceModeConfig> map = new TreeMap<String, ServiceModeConfig>();
BufferedReader br = null; BufferedReader br = null;
String modesFile = modesDir + "/serviceconfig.dat"; String modesFile = modesDir + "/serviceconfig.dat";
try try
{ {
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 ) break; if ( line == null )
break;
ServiceModeConfig smc = new ServiceModeConfig( line ); ServiceModeConfig smc = new ServiceModeConfig( line );
map.put( smc.mode, smc ); map.put( smc.mode, smc );
} }
} }
catch( Exception e ) {} catch (Exception e)
{
}
finally finally
{ {
if ( br != null ) try { br.close(); } catch( Exception ee ) {} if ( br != null )
try
{
br.close();
}
catch (Exception ee)
{
}
} }
// replace selected modes // replace selected modes
for( int i=0; i<6; i++) for ( int i = 0; i < 6; i++ )
{ {
if ( checkedModes[i] ) if ( checkedModes[i] )
{ {
writeRawTrackToMode( routingModes[i] ); writeRawTrackToMode( routingModes[i] );
ServiceModeConfig smc = new ServiceModeConfig( routingModes[i], profileName); ServiceModeConfig smc = new ServiceModeConfig( routingModes[i], profileName );
for( OsmNodeNamed nogo : nogoVetoList) for ( OsmNodeNamed nogo : nogoVetoList )
{ {
smc.nogoVetos.add( nogo.ilon + "," + nogo.ilat ); smc.nogoVetos.add( nogo.ilon + "," + nogo.ilat );
} }
@ -747,27 +830,35 @@ private long startTime = 0L;
} }
} }
// no write new config // no write new config
BufferedWriter bw = null; BufferedWriter bw = null;
StringBuilder msg = new StringBuilder( "Mode mapping is now:\n" ); StringBuilder msg = new StringBuilder( "Mode mapping is now:\n" );
msg.append( "( [..] counts nogo-vetos)\n" ); msg.append( "( [..] counts nogo-vetos)\n" );
try try
{ {
bw = new BufferedWriter( new FileWriter ( modesFile ) ); bw = new BufferedWriter( new FileWriter( modesFile ) );
for( ServiceModeConfig smc : map.values() ) for ( ServiceModeConfig smc : map.values() )
{ {
bw.write( smc.toLine() ); bw.write( smc.toLine() );
bw.write( '\n' ); bw.write( '\n' );
msg.append( smc.toString() ).append( '\n' ); msg.append( smc.toString() ).append( '\n' );
} }
} }
catch( Exception e ) {} catch (Exception e)
{
}
finally finally
{ {
if ( bw != null ) try { bw.close(); } catch( Exception ee ) {} if ( bw != null )
try
{
bw.close();
} }
((BRouterActivity)getContext()).showModeConfigOverview( msg.toString() ); catch (Exception ee)
{
}
}
( (BRouterActivity) getContext() ).showModeConfigOverview( msg.toString() );
} }
private String readSingleLineFile( File f ) private String readSingleLineFile( File f )
@ -775,16 +866,25 @@ private long startTime = 0L;
BufferedReader br = null; BufferedReader br = null;
try try
{ {
br = new BufferedReader( new InputStreamReader ( new FileInputStream( f ) ) ); br = new BufferedReader( new InputStreamReader( new FileInputStream( f ) ) );
return br.readLine(); return br.readLine();
} }
catch( Exception e ) { return null; } catch (Exception e)
{
return null;
}
finally finally
{ {
if ( br != null ) try { br.close(); } catch( Exception ee ) {} if ( br != null )
try
{
br.close();
}
catch (Exception ee)
{
}
} }
} }
private static List<String> getStorageDirectories() private static List<String> getStorageDirectories()
{ {
@ -793,21 +893,24 @@ private long startTime = 0L;
BufferedReader br = null; BufferedReader br = null;
try try
{ {
br = new BufferedReader(new FileReader("/proc/mounts")); br = new BufferedReader( new FileReader( "/proc/mounts" ) );
for(;;) for ( ;; )
{ {
String line = br.readLine(); String line = br.readLine();
if ( line == null ) break; if ( line == null )
if (line.indexOf("vfat") < 0 && line.indexOf("/mnt") < 0 ) continue; break;
StringTokenizer tokens = new StringTokenizer(line, " "); if ( line.indexOf( "vfat" ) < 0 && line.indexOf( "/mnt" ) < 0 )
continue;
StringTokenizer tokens = new StringTokenizer( line, " " );
tokens.nextToken(); tokens.nextToken();
String d = tokens.nextToken(); String d = tokens.nextToken();
boolean isExternalDir = false; boolean isExternalDir = false;
if ( line.contains( "/dev/block/vold" ) ) if ( line.contains( "/dev/block/vold" ) )
{ {
isExternalDir = true; isExternalDir = true;
String[] vetos = new String[] { "/mnt/secure", "/mnt/asec", "/mnt/obb", "/dev/mapper", "tmpfs", "/mnt/media_rw" }; String[] vetos = new String[]
for( String v: vetos ) { "/mnt/secure", "/mnt/asec", "/mnt/obb", "/dev/mapper", "tmpfs", "/mnt/media_rw" };
for ( String v : vetos )
{ {
if ( d.indexOf( v ) >= 0 ) if ( d.indexOf( v ) >= 0 )
{ {
@ -824,10 +927,21 @@ private long startTime = 0L;
} }
} }
} }
catch ( Exception e) { /* ignore */ } catch (Exception e)
{ /* ignore */
}
finally finally
{ {
if (br != null) { try { br.close(); } catch (Exception e) { /* ignore */ } } if ( br != null )
{
try
{
br.close();
}
catch (Exception e)
{ /* ignore */
}
}
} }
return res; return res;
} }

View file

@ -9,10 +9,6 @@ import java.io.OutputStreamWriter;
import android.content.Context; import android.content.Context;
/**
* Decsription of a service config
*/
public class ConfigHelper public class ConfigHelper
{ {
public static String getBaseDir( Context ctx ) public static String getBaseDir( Context ctx )
@ -22,13 +18,25 @@ public class ConfigHelper
try try
{ {
configInput = ctx.openFileInput( "config.dat" ); configInput = ctx.openFileInput( "config.dat" );
BufferedReader br = new BufferedReader( new InputStreamReader (configInput ) ); BufferedReader br = new BufferedReader( new InputStreamReader( configInput ) );
return br.readLine(); return br.readLine();
} }
catch( Exception e ) { return null; } catch (Exception e)
{
return null;
}
finally finally
{ {
if ( configInput != null ) try { configInput.close(); } catch( Exception ee ) {} if ( configInput != null )
{
try
{
configInput.close();
}
catch (Exception ee)
{
}
}
} }
} }
@ -38,14 +46,19 @@ public class ConfigHelper
try try
{ {
OutputStream configOutput = ctx.openFileOutput( "config.dat", Context.MODE_PRIVATE ); OutputStream configOutput = ctx.openFileOutput( "config.dat", Context.MODE_PRIVATE );
bw = new BufferedWriter( new OutputStreamWriter (configOutput ) ); bw = new BufferedWriter( new OutputStreamWriter( configOutput ) );
bw.write( baseDir ); bw.write( baseDir );
bw.write( '\n' ); bw.write( '\n' );
} }
catch( Exception e ) {} catch (Exception e){ /* ignore */ }
finally finally
{ {
if ( bw != null ) try { bw.close(); } catch( Exception ee ) {} if ( bw != null )
try
{
bw.close();
}
catch (Exception ee) { /* ignore */ }
} }
} }
} }

View file

@ -0,0 +1,89 @@
package btools.routingapp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
public class ConfigMigration
{
public static void tryMigrateStorageConfig( File srcFile, File dstFile )
{
if ( !srcFile.exists() ) return;
String ssd = null;
String amd = null;
BufferedReader br = null;
BufferedWriter bw = null;
try
{
br = new BufferedReader( new FileReader( srcFile ) );
for ( ;; )
{
String line = br.readLine();
if ( line == null ) break;
if ( line.trim().startsWith( "secondary_segment_dir=" ) )
{
if ( !"secondary_segment_dir=../segments2".equals( line ) )
{
ssd = line;
}
}
if ( line.trim().startsWith( "additional_maptool_dir=" ) )
{
amd = line;
}
}
br.close();
List<String> lines = new ArrayList<String>();
br = new BufferedReader( new FileReader( dstFile ) );
for ( ;; )
{
String line = br.readLine();
if ( line == null ) break;
if ( ssd != null && line.trim().startsWith( "secondary_segment_dir=" ) )
{
line = ssd;
}
if ( amd != null && line.trim().startsWith( "#additional_maptool_dir=" ) )
{
line = amd;
}
lines.add( line );
}
br.close();
br = null;
bw = new BufferedWriter( new FileWriter( dstFile ) );
for( String line: lines )
{
bw.write( line + "\n" );
}
}
catch (Exception e) { /* ignore */ }
finally
{
if ( br != null )
{
try
{
br.close();
}
catch (Exception ee) { /* ignore */ }
}
if ( bw != null )
{
try
{
bw.close();
}
catch (Exception ee) { /* ignore */ }
}
}
}
}

View file

@ -4,8 +4,11 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.os.Environment; import android.os.Environment;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
@ -22,7 +25,9 @@ public abstract class CoordinateReader
public String rootdir; public String rootdir;
public String tracksdir; public String tracksdir;
public Map<String,OsmNodeNamed> allpoints; private Map<String,Map<String, OsmNodeNamed>> allpointsMap;
public List<OsmNodeNamed> allpoints;
private HashMap<String,OsmNodeNamed> pointmap; private HashMap<String,OsmNodeNamed> pointmap;
protected static String[] posnames protected static String[] posnames
@ -35,6 +40,34 @@ public abstract class CoordinateReader
public abstract long getTimeStamp() throws Exception; public abstract long getTimeStamp() throws Exception;
public void readAllPoints() throws Exception
{
allpointsMap = new TreeMap<String, Map<String,OsmNodeNamed>>();
readFromTo();
allpoints = new ArrayList<OsmNodeNamed>();
Set<String> names = new HashSet<String>();
for( String category : allpointsMap.keySet() )
{
Map<String, OsmNodeNamed> cat = allpointsMap.get( category );
if ( cat.size() < 101 )
{
for ( OsmNodeNamed wp : cat.values() )
{
if ( names.add( wp.name ) )
{
allpoints.add( wp );
}
}
}
else
{
OsmNodeNamed nocatHint = new OsmNodeNamed();
nocatHint.name = "<big category " + category + " supressed>";
allpoints.add( nocatHint);
}
}
}
/* /*
* read the from, to and via-positions from a gpx-file * read the from, to and via-positions from a gpx-file
*/ */
@ -62,11 +95,21 @@ public abstract class CoordinateReader
if ( fromToMissing ) waypoints.clear(); if ( fromToMissing ) waypoints.clear();
} }
protected void checkAddPoint( OsmNodeNamed n ) protected void checkAddPoint( String category, OsmNodeNamed n )
{ {
if ( allpoints != null ) if ( allpointsMap != null )
{ {
allpoints.put( n.name, n ); if ( category == null ) category = "";
Map<String, OsmNodeNamed> cat = allpointsMap.get( category );
if ( cat == null )
{
cat = new TreeMap<String, OsmNodeNamed>();
allpointsMap.put( category, cat );
}
if ( cat.size() < 101 )
{
cat.put( n.name, n );
}
return; return;
} }
@ -104,9 +147,9 @@ public abstract class CoordinateReader
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>(); ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
AppLogger.log( "adding standard maptool-base: " + basedir ); AppLogger.log( "adding standard maptool-base: " + basedir );
rl.add( new CoordinateReaderOsmAnd(basedir) ); rl.add( new CoordinateReaderOsmAnd( basedir ) );
rl.add( new CoordinateReaderLocus(basedir) ); rl.add( new CoordinateReaderLocus( basedir ) );
rl.add( new CoordinateReaderOrux(basedir) ); rl.add( new CoordinateReaderOrux( basedir ) );
// eventually add standard-sd // eventually add standard-sd
File standardbase = Environment.getExternalStorageDirectory(); File standardbase = Environment.getExternalStorageDirectory();
@ -116,27 +159,28 @@ public abstract class CoordinateReader
if ( !base2.equals( basedir ) ) if ( !base2.equals( basedir ) )
{ {
AppLogger.log( "adding internal sd maptool-base: " + base2 ); AppLogger.log( "adding internal sd maptool-base: " + base2 );
rl.add( new CoordinateReaderOsmAnd(base2) ); rl.add( new CoordinateReaderOsmAnd( base2 ) );
rl.add( new CoordinateReaderLocus(base2) ); rl.add( new CoordinateReaderLocus( base2 ) );
rl.add( new CoordinateReaderOrux(base2) ); rl.add( new CoordinateReaderOrux( base2 ) );
} }
} }
// eventually add explicit directory // eventually add explicit directory
File additional = RoutingHelper.getAdditionalMaptoolDir(segmentDir); File additional = RoutingHelper.getAdditionalMaptoolDir( segmentDir );
if ( additional != null ) if ( additional != null )
{ {
String base3 = additional.getAbsolutePath(); String base3 = additional.getAbsolutePath();
AppLogger.log( "adding maptool-base from storage-config: " + base3 ); AppLogger.log( "adding maptool-base from storage-config: " + base3 );
rl.add( new CoordinateReaderOsmAnd(base3) ); rl.add( new CoordinateReaderOsmAnd( base3 ) );
rl.add( new CoordinateReaderLocus(base3) ); rl.add( new CoordinateReaderOsmAnd( base3, true ) );
rl.add( new CoordinateReaderOrux(base3) ); rl.add( new CoordinateReaderLocus( base3 ) );
rl.add( new CoordinateReaderOrux( base3 ) );
} }
long tmax = 0; long tmax = 0;
for( CoordinateReader r : rl ) for ( CoordinateReader r : rl )
{ {
if ( AppLogger.isLogging() ) if ( AppLogger.isLogging() )
{ {

View file

@ -38,14 +38,16 @@ public class CoordinateReaderLocus extends CoordinateReader
private void _readPointmap( String filename ) throws Exception private void _readPointmap( String filename ) throws Exception
{ {
SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY); SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY);
Cursor c = myDataBase.rawQuery("SELECT name, longitude, latitude FROM waypoints", 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);
while (c.moveToNext()) while (c.moveToNext())
{ {
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
n.name = c.getString(0); String category = c.getString(0);
n.ilon = (int)( ( Double.parseDouble( c.getString(1) ) + 180. )*1000000. + 0.5); n.name = c.getString(1);
n.ilat = (int)( ( Double.parseDouble( c.getString(2) ) + 90. )*1000000. + 0.5); n.ilon = (int)( ( Double.parseDouble( c.getString(2) ) + 180. )*1000000. + 0.5);
checkAddPoint( n ); n.ilat = (int)( ( Double.parseDouble( c.getString(3) ) + 90. )*1000000. + 0.5);
checkAddPoint( category, n );
} }
myDataBase.close(); myDataBase.close();
} }

View file

@ -38,14 +38,15 @@ public class CoordinateReaderOrux extends CoordinateReader
private void _readPointmap( String filename ) throws Exception private void _readPointmap( String filename ) throws Exception
{ {
SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY); SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase( filename, null, SQLiteDatabase.OPEN_READONLY);
Cursor c = myDataBase.rawQuery("SELECT poiname, poilon, poilat 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)( ( Double.parseDouble( c.getString(1) ) + 180. )*1000000. + 0.5); n.ilon = (int)( ( Double.parseDouble( c.getString(1) ) + 180. )*1000000. + 0.5);
n.ilat = (int)( ( Double.parseDouble( c.getString(2) ) + 90. )*1000000. + 0.5); n.ilat = (int)( ( Double.parseDouble( c.getString(2) ) + 90. )*1000000. + 0.5);
checkAddPoint( n ); String category = c.getString(3);
checkAddPoint( category, n );
} }
myDataBase.close(); myDataBase.close();
} }

View file

@ -12,18 +12,35 @@ import btools.router.OsmNodeNamed;
*/ */
public class CoordinateReaderOsmAnd extends CoordinateReader public class CoordinateReaderOsmAnd extends CoordinateReader
{ {
private String osmandDir;
public CoordinateReaderOsmAnd( String basedir ) public CoordinateReaderOsmAnd( String basedir )
{
this( basedir, false );
}
public CoordinateReaderOsmAnd( String basedir, boolean shortPath )
{ {
super( basedir ); super( basedir );
if ( shortPath )
{
osmandDir = basedir;
tracksdir = "/tracks";
rootdir = "";
}
else
{
osmandDir = basedir + "/osmand";
tracksdir = "/osmand/tracks"; tracksdir = "/osmand/tracks";
rootdir = "/osmand"; rootdir = "/osmand";
} }
}
@Override @Override
public long getTimeStamp() throws Exception public long getTimeStamp() throws Exception
{ {
long t1 = new File( basedir + "/osmand/favourites_bak.gpx" ).lastModified(); long t1 = new File( osmandDir + "/favourites_bak.gpx" ).lastModified();
long t2 = new File( basedir + "/osmand/favourites.gpx" ).lastModified(); long t2 = new File( osmandDir + "/favourites.gpx" ).lastModified();
return t1 > t2 ? t1 : t2; return t1 > t2 ? t1 : t2;
} }
@ -36,11 +53,11 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
{ {
try try
{ {
_readPointmap( basedir + "/osmand/favourites_bak.gpx" ); _readPointmap( osmandDir + "/favourites_bak.gpx" );
} }
catch( Exception e ) catch( Exception e )
{ {
_readPointmap( basedir + "/osmand/favourites.gpx" ); _readPointmap( osmandDir + "/favourites.gpx" );
} }
} }
@ -78,7 +95,7 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
if ( idx11 >= 0 ) if ( idx11 >= 0 )
{ {
n.name = line.substring( idx10, idx11 ).trim(); n.name = line.substring( idx10, idx11 ).trim();
checkAddPoint( n ); checkAddPoint( "(one-for-all)", n );
} }
} }
} }

View file

@ -88,7 +88,7 @@ public class BRouter
} }
System.exit(0); System.exit(0);
} }
System.out.println("BRouter 1.3.1 / 18102015 / abrensch"); System.out.println("BRouter 1.3.2 / 31102015 / abrensch");
if ( args.length < 6 ) if ( args.length < 6 )
{ {
System.out.println("Find routes in an OSM map"); System.out.println("Find routes in an OSM map");

View file

@ -155,7 +155,7 @@ public class RouteServer extends Thread
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
System.out.println("BRouter 1.3.1 / 18102015"); System.out.println("BRouter 1.3.2 / 31102015");
if ( args.length != 5 ) if ( args.length != 5 )
{ {
System.out.println("serve BRouter protocol"); System.out.println("serve BRouter protocol");

View file

@ -1,395 +1,131 @@
package btools.util; package btools.util;
import java.io.*; import java.io.ByteArrayOutputStream;
import java.util.zip.*; import java.io.IOException;
import java.util.zip.CRC32;
public class Raster2Png extends Object { import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
/** Constant specifying that alpha channel should be encoded. */
public static final boolean ENCODE_ALPHA = true;
/** Constant specifying that alpha channel should not be encoded. */
public static final boolean NO_ALPHA = false;
public class Raster2Png extends ByteDataWriter
{
/** Constants for filter (NONE) */ /** Constants for filter (NONE) */
public static final int FILTER_NONE = 0; public static final int FILTER_NONE = 0;
/** Constants for filter (SUB) */
public static final int FILTER_SUB = 1;
/** Constants for filter (UP) */
public static final int FILTER_UP = 2;
/** Constants for filter (LAST) */
public static final int FILTER_LAST = 2;
/** IHDR tag. */ /** IHDR tag. */
protected static final byte IHDR[] = {73, 72, 68, 82}; protected static final byte IHDR[] = { 73, 72, 68, 82 };
/** IDAT tag. */ /** IDAT tag. */
protected static final byte IDAT[] = {73, 68, 65, 84}; protected static final byte IDAT[] = { 73, 68, 65, 84 };
/** IEND tag. */ /** IEND tag. */
protected static final byte IEND[] = {73, 69, 78, 68}; protected static final byte IEND[] = { 73, 69, 78, 68 };
/** The png bytes. */ /** geometry */
protected byte[] pngBytes;
/** The prior row. */
protected byte[] priorRow;
/** The left bytes. */
protected byte[] leftBytes;
/** The width. */
protected int width, height; protected int width, height;
/** The byte position. */
protected int bytePos, maxPos;
protected int[] imagePixels; protected int[] imagePixels;
/** CRC. */ /** CRC. */
protected CRC32 crc = new CRC32(); protected CRC32 crc = new CRC32();
/** The CRC value. */ public Raster2Png()
protected long crcValue; {
super( null );
/** The filter type. */ }
protected int filter;
/** The bytes-per-pixel. */
protected int bytesPerPixel;
/** The compression level. */
protected int compressionLevel;
private boolean encodeAlpha = false;
/** /**
* Class constructor specifying filter to use and compression level. * Converts a pixel array to it's PNG equivalent
*
* @param whichFilter 0=none, 1=sub, 2=up
* @param compLevel 0..9
*/ */
public Raster2Png(int whichFilter, int compLevel, int width, int height, int[] imagePixels ) { public byte[] pngEncode( int width, int height, int[] imagePixels ) throws IOException
{
this.width = width; this.width = width;
this.height = height; this.height = height;
this.imagePixels = imagePixels; this.imagePixels = imagePixels;
setFilter(whichFilter); // user a buffer large enough to hold the png
ab = new byte[( ( width + 1 ) * height * 3 ) + 200];
if (compLevel >= 0 && compLevel <= 9) { byte[] pngIdBytes =
this.compressionLevel = compLevel; { -119, 80, 78, 71, 13, 10, 26, 10 };
} write( pngIdBytes );
}
/**
* Creates an array of bytes that is the PNG equivalent of the current image, specifying
* whether to encode alpha or not.
*
* @param encodeAlpha boolean false=no alpha, true=encode alpha
* @return an array of bytes, or null if there was a problem
*/
public byte[] pngEncode() {
byte[] pngIdBytes = {-119, 80, 78, 71, 13, 10, 26, 10};
if (imagePixels == null) {
return null;
}
/*
* start with an array that is big enough to hold all the pixels
* (plus filter bytes), and an extra 200 bytes for header info
*/
pngBytes = new byte[((width + 1) * height * 3) + 200];
/*
* keep track of largest byte written to the array
*/
maxPos = 0;
bytePos = writeBytes(pngIdBytes, 0);
//hdrPos = bytePos;
writeHeader(); writeHeader();
//dataPos = bytePos; writeImageData();
if (writeImageData()) { return toByteArray();
writeEnd();
pngBytes = resizeByteArray(pngBytes, maxPos);
}
else {
pngBytes = null;
}
return pngBytes;
}
/**
* Set the filter to use
*
* @param whichFilter from constant list
*/
public void setFilter(int whichFilter) {
this.filter = FILTER_NONE;
if (whichFilter <= FILTER_LAST) {
this.filter = whichFilter;
}
}
/**
* Set the compression level to use
*
* @param level 0 through 9
*/
public void setCompressionLevel(int level) {
if (level >= 0 && level <= 9) {
this.compressionLevel = level;
}
}
/**
* Increase or decrease the length of a byte array.
*
* @param array The original array.
* @param newLength The length you wish the new array to have.
* @return Array of newly desired length. If shorter than the
* original, the trailing elements are truncated.
*/
protected byte[] resizeByteArray(byte[] array, int newLength) {
byte[] newArray = new byte[newLength];
int oldLength = array.length;
System.arraycopy(array, 0, newArray, 0, Math.min(oldLength, newLength));
return newArray;
}
/**
* Write an array of bytes into the pngBytes array.
* Note: This routine has the side effect of updating
* maxPos, the largest element written in the array.
* The array is resized by 1000 bytes or the length
* of the data to be written, whichever is larger.
*
* @param data The data to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeBytes(byte[] data, int offset) {
maxPos = Math.max(maxPos, offset + data.length);
if (data.length + offset > pngBytes.length) {
pngBytes = resizeByteArray(pngBytes, pngBytes.length + Math.max(1000, data.length));
}
System.arraycopy(data, 0, pngBytes, offset, data.length);
return offset + data.length;
}
/**
* Write an array of bytes into the pngBytes array, specifying number of bytes to write.
* Note: This routine has the side effect of updating
* maxPos, the largest element written in the array.
* The array is resized by 1000 bytes or the length
* of the data to be written, whichever is larger.
*
* @param data The data to be written into pngBytes.
* @param nBytes The number of bytes to be written.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeBytes(byte[] data, int nBytes, int offset) {
maxPos = Math.max(maxPos, offset + nBytes);
if (nBytes + offset > pngBytes.length) {
pngBytes = resizeByteArray(pngBytes, pngBytes.length + Math.max(1000, nBytes));
}
System.arraycopy(data, 0, pngBytes, offset, nBytes);
return offset + nBytes;
}
/**
* Write a two-byte integer into the pngBytes array at a given position.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeInt2(int n, int offset) {
byte[] temp = {(byte) ((n >> 8) & 0xff), (byte) (n & 0xff)};
return writeBytes(temp, offset);
}
/**
* Write a four-byte integer into the pngBytes array at a given position.
*
* @param n The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeInt4(int n, int offset) {
byte[] temp = {(byte) ((n >> 24) & 0xff),
(byte) ((n >> 16) & 0xff),
(byte) ((n >> 8) & 0xff),
(byte) (n & 0xff)};
return writeBytes(temp, offset);
}
/**
* Write a single byte into the pngBytes array at a given position.
*
* @param b The integer to be written into pngBytes.
* @param offset The starting point to write to.
* @return The next place to be written to in the pngBytes array.
*/
protected int writeByte(int b, int offset) {
byte[] temp = {(byte) b};
return writeBytes(temp, offset);
} }
/** /**
* Write a PNG "IHDR" chunk into the pngBytes array. * Write a PNG "IHDR" chunk into the pngBytes array.
*/ */
protected void writeHeader() { protected void writeHeader()
int startPos; {
writeInt( 13 );
startPos = bytePos = writeInt4(13, bytePos); int startPos = aboffset;
bytePos = writeBytes(IHDR, bytePos); write( IHDR );
bytePos = writeInt4(width, bytePos); writeInt( width );
bytePos = writeInt4(height, bytePos); writeInt( height );
bytePos = writeByte(8, bytePos); // bit depth writeByte( 8 ); // bit depth
bytePos = writeByte((encodeAlpha) ? 6 : 2, bytePos); // direct model writeByte( 2 ); // direct model
bytePos = writeByte(0, bytePos); // compression method writeByte( 0 ); // compression method
bytePos = writeByte(0, bytePos); // filter method writeByte( 0 ); // filter method
bytePos = writeByte(0, bytePos); // no interlace writeByte( 0 ); // no interlace
crc.reset(); crc.reset();
crc.update(pngBytes, startPos, bytePos - startPos); crc.update( ab, startPos, aboffset - startPos );
crcValue = crc.getValue(); writeInt( (int) crc.getValue() );
bytePos = writeInt4((int) crcValue, bytePos);
} }
/** /**
* Perform "sub" filtering on the given row. * Write the image data into the pngBytes array. This will write one or more
* Uses temporary array leftBytes to store the original values * PNG "IDAT" chunks. In order to conserve memory, this method grabs as many
* of the previous pixels. The array is 16 bytes long, which * rows as will fit into 32K bytes, or the whole image; whichever is less.
* will easily hold two-byte samples plus two-byte alpha.
*
* @param pixels The array holding the scan lines being built
* @param startPos Starting position within pixels of bytes to be filtered.
* @param width Width of a scanline in pixels.
*/ */
protected void filterSub(byte[] pixels, int startPos, int width) { protected void writeImageData() throws IOException
int i; {
int offset = bytesPerPixel;
int actualStart = startPos + offset;
int nBytes = width * bytesPerPixel;
int leftInsert = offset;
int leftExtract = 0;
for (i = actualStart; i < startPos + nBytes; i++) {
leftBytes[leftInsert] = pixels[i];
pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
leftInsert = (leftInsert + 1) % 0x0f;
leftExtract = (leftExtract + 1) % 0x0f;
}
}
/**
* Perform "up" filtering on the given row.
* Side effect: refills the prior row with current row
*
* @param pixels The array holding the scan lines being built
* @param startPos Starting position within pixels of bytes to be filtered.
* @param width Width of a scanline in pixels.
*/
protected void filterUp(byte[] pixels, int startPos, int width) {
int i, nBytes;
byte currentByte;
nBytes = width * bytesPerPixel;
for (i = 0; i < nBytes; i++) {
currentByte = pixels[startPos + i];
pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
priorRow[i] = currentByte;
}
}
/**
* Write the image data into the pngBytes array.
* This will write one or more PNG "IDAT" chunks. In order
* to conserve memory, this method grabs as many rows as will
* fit into 32K bytes, or the whole image; whichever is less.
*
*
* @return true if no errors; false if error grabbing pixels
*/
protected boolean writeImageData() {
int rowsLeft = height; // number of rows remaining to write int rowsLeft = height; // number of rows remaining to write
int startRow = 0; // starting row to process this time through int startRow = 0; // starting row to process this time through
int nRows; // how many rows to grab at a time int nRows; // how many rows to grab at a time
byte[] scanLines; // the scan lines to be compressed byte[] scanLines; // the scan lines to be compressed
int scanPos; // where we are in the scan lines int scanPos; // where we are in the scan lines
int startPos; // where this line's actual pixels start (used for filtering)
byte[] compressedLines; // the resultant compressed lines byte[] compressedLines; // the resultant compressed lines
int nCompressed; // how big is the compressed area? int nCompressed; // how big is the compressed area?
//int depth; // color depth ( handle only 8 or 32 ) int bytesPerPixel = 3;
// PixelGrabber pg; Deflater scrunch = new Deflater( 6 );
ByteArrayOutputStream outBytes = new ByteArrayOutputStream( 1024 );
bytesPerPixel = (encodeAlpha) ? 4 : 3; DeflaterOutputStream compBytes = new DeflaterOutputStream( outBytes, scrunch );
while (rowsLeft > 0)
Deflater scrunch = new Deflater(compressionLevel); {
ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024); nRows = Math.min( 32767 / ( width * ( bytesPerPixel + 1 ) ), rowsLeft );
DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
try {
while (rowsLeft > 0) {
nRows = Math.min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
nRows = Math.max( nRows, 1 ); nRows = Math.max( nRows, 1 );
int[] pixels = new int[width * nRows]; int[] pixels = new int[width * nRows];
getPixels(startRow, nRows, pixels); getPixels( startRow, nRows, pixels );
/* /*
* Create a data chunk. scanLines adds "nRows" for * Create a data chunk. scanLines adds "nRows" for the filter bytes.
* the filter bytes.
*/ */
scanLines = new byte[width * nRows * bytesPerPixel + nRows]; scanLines = new byte[width * nRows * bytesPerPixel + nRows];
if (filter == FILTER_SUB) {
leftBytes = new byte[16];
}
if (filter == FILTER_UP) {
priorRow = new byte[width * bytesPerPixel];
}
scanPos = 0; scanPos = 0;
startPos = 1; for ( int i = 0; i < width * nRows; i++ )
for (int i = 0; i < width * nRows; i++) { {
if (i % width == 0) { if ( i % width == 0 )
scanLines[scanPos++] = (byte) filter; {
startPos = scanPos; scanLines[scanPos++] = (byte) FILTER_NONE;
}
scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
if (encodeAlpha) {
scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
}
if ((i % width == width - 1) && (filter != FILTER_NONE)) {
if (filter == FILTER_SUB) {
filterSub(scanLines, startPos, width);
}
if (filter == FILTER_UP) {
filterUp(scanLines, startPos, width);
}
} }
scanLines[scanPos++] = (byte) ( ( pixels[i] >> 16 ) & 0xff );
scanLines[scanPos++] = (byte) ( ( pixels[i] >> 8 ) & 0xff );
scanLines[scanPos++] = (byte) ( ( pixels[i] ) & 0xff );
} }
/* /*
* Write these lines to the output area * Write these lines to the output area
*/ */
compBytes.write(scanLines, 0, scanPos); compBytes.write( scanLines, 0, scanPos );
startRow += nRows; startRow += nRows;
rowsLeft -= nRows; rowsLeft -= nRows;
@ -403,62 +139,32 @@ public class Raster2Png extends Object {
nCompressed = compressedLines.length; nCompressed = compressedLines.length;
crc.reset(); crc.reset();
bytePos = writeInt4(nCompressed, bytePos); writeInt( nCompressed );
bytePos = writeBytes(IDAT, bytePos); write( IDAT );
crc.update(IDAT); crc.update( IDAT );
bytePos = writeBytes(compressedLines, nCompressed, bytePos); write( compressedLines );
crc.update(compressedLines, 0, nCompressed); crc.update( compressedLines, 0, nCompressed );
crcValue = crc.getValue(); writeInt( (int) crc.getValue() );
bytePos = writeInt4((int) crcValue, bytePos);
scrunch.finish(); scrunch.finish();
return true;
}
catch (IOException e) {
System.err.println(e.toString());
return false;
}
}
/** // Write a PNG "IEND" chunk into the pngBytes array.
* Write a PNG "IEND" chunk into the pngBytes array. writeInt( 0 );
*/ write( IEND );
protected void writeEnd() {
bytePos = writeInt4(0, bytePos);
bytePos = writeBytes(IEND, bytePos);
crc.reset(); crc.reset();
crc.update(IEND); crc.update( IEND );
crcValue = crc.getValue(); writeInt( (int) crc.getValue() );
bytePos = writeInt4((int) crcValue, bytePos);
} }
private void getPixels( int startRow, int nRows, int[] pixels) private void getPixels( int startRow, int nRows, int[] pixels )
{ {
for( int i=0; i<nRows; i++ ) for ( int i = 0; i < nRows; i++ )
{ {
int ir = i + startRow; int ir = i + startRow;
for( int ic=0; ic<width; ic++ ) for ( int ic = 0; ic < width; ic++ )
{ {
pixels[ i*width + ic ] = imagePixels[ ir*width + ic]; pixels[i * width + ic] = imagePixels[ir * width + ic];
} }
} }
} }
private int pseudoLog( short sval )
{
int val = 30 + sval;
if ( val < 0 ) { val = 0; }
if ( val > 2000 ) return 255;
int res = 0;
int div = 1;
while ( val > 0 )
{
int d = val > 127 ? 127 : val;
val -= d;
res += d / div;
div *= 2;
}
return res < 255 ? res : 255;
}
} }