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

@ -21,9 +21,8 @@ public class TrafficData2Png
{ {
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 )
{ {
@ -41,8 +40,8 @@ public class TrafficData2Png
} }
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 );
@ -56,7 +55,8 @@ public class TrafficData2Png
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[]
{ 1, 2, 3, 4, 5, 6, 7, -1 };
for ( int tclass : tclasses ) for ( int tclass : tclasses )
{ {
for ( long key : keys ) for ( long key : keys )
@ -67,7 +67,8 @@ public class TrafficData2Png
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,9 +90,7 @@ 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 ) ) );
@ -117,7 +116,8 @@ public class TrafficData2Png
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 ) )
{ {

View file

@ -44,10 +44,17 @@ public class StorageConfigHelper
} }
} }
} }
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,15 +44,15 @@ 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 );
@ -70,8 +70,10 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 );
} }
@ -80,45 +82,54 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 ); Intent intent = new Intent( BRouterActivity.this, BInstallerActivity.class );
startActivity( intent ); 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();
} }
} ); } );
@ -126,25 +137,28 @@ public class BRouterActivity extends Activity implements OnInitListener {
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) { {
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.configureService( routingModes, routingModesChecked ); 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();
} }
} ); } );
@ -156,8 +170,10 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 );
} }
@ -166,14 +182,16 @@ public class BRouterActivity extends Activity implements OnInitListener {
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() )
@ -190,11 +208,11 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 @Override
public void onClick(DialogInterface dialog, int which, public void onClick( DialogInterface dialog, int which, boolean isChecked )
boolean isChecked) { {
if ( isChecked ) if ( isChecked )
{ {
selectedVias.add( availableVias[which] ); selectedVias.add( availableVias[which] );
@ -205,8 +223,10 @@ public class BRouterActivity extends Activity implements OnInitListener {
} }
} }
} ); } );
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 );
} }
@ -216,17 +236,21 @@ public class BRouterActivity extends Activity implements OnInitListener {
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++ )
nogoNames[i] = nogoList.get( i ).name;
final boolean[] nogoEnabled = getCheckedBooleanArray( nogoList.size() ); final boolean[] nogoEnabled = getCheckedBooleanArray( nogoList.size() );
builder.setMultiChoiceItems(nogoNames, getCheckedBooleanArray( nogoNames.length ), builder.setMultiChoiceItems( nogoNames, getCheckedBooleanArray( nogoNames.length ), new DialogInterface.OnMultiChoiceClickListener()
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 );
} }
@ -236,17 +260,21 @@ public class BRouterActivity extends Activity implements OnInitListener {
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();
@ -257,10 +285,10 @@ public class BRouterActivity extends Activity implements OnInitListener {
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();
} }
} ); } );
@ -268,8 +296,10 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 );
} }
@ -279,7 +309,6 @@ public class BRouterActivity extends Activity implements OnInitListener {
default: default:
return null; return null;
} }
} }
private boolean[] getCheckedBooleanArray( int size ) private boolean[] getCheckedBooleanArray( int size )
@ -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")
@ -360,7 +388,8 @@ public class BRouterActivity extends Activity implements OnInitListener {
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 ) );
} }
@ -372,8 +401,7 @@ public class BRouterActivity extends Activity implements OnInitListener {
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,19 +72,19 @@ 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 );
@ -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";
}
} }
} }
@ -192,18 +231,17 @@ public class BRouterView extends View
{ {
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 ) )
@ -216,9 +254,8 @@ public class BRouterView extends View
} }
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 ) );
@ -228,6 +265,7 @@ public class BRouterView extends View
waitingForSelection = true; waitingForSelection = true;
} }
public boolean hasUpToDateLookups() public boolean hasUpToDateLookups()
{ {
BExpressionMetaData meta = new BExpressionMetaData(); BExpressionMetaData meta = new BExpressionMetaData();
@ -269,16 +307,23 @@ 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 )
{ {
@ -286,17 +331,27 @@ public class BRouterView extends View
} }
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 )
wpts[i++] = wp.name;
( (BRouterActivity) getContext() ).selectWaypoint( wpts ); ( (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()
@ -336,7 +391,8 @@ 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;
@ -383,8 +436,10 @@ public class BRouterView extends View
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 );
@ -402,8 +457,7 @@ public class BRouterView extends View
} }
} }
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() )
@ -421,19 +475,22 @@ public class BRouterView extends View
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)
{ {
@ -442,7 +499,9 @@ public class BRouterView extends View
} }
} }
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 )
@ -478,7 +537,8 @@ public class BRouterView extends View
} }
@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 )
@ -487,12 +547,12 @@ public class BRouterView extends View
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 );
@ -500,24 +560,40 @@ private long startTime = 0L;
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
{
Thread.sleep( 2000 );
}
catch (InterruptedException ie)
{
}
( (BRouterActivity) getContext() ).showErrorMessage( t.toString() ); ( (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() )
@ -533,15 +609,14 @@ private long startTime = 0L;
} }
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;
@ -590,7 +665,6 @@ private long startTime = 0L;
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 );
@ -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
@ -721,15 +794,25 @@ private long startTime = 0L;
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
@ -747,7 +830,6 @@ 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" );
@ -762,10 +844,19 @@ private long startTime = 0L;
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();
}
catch (Exception ee)
{
}
} }
( (BRouterActivity) getContext() ).showModeConfigOverview( msg.toString() ); ( (BRouterActivity) getContext() ).showModeConfigOverview( msg.toString() );
} }
@ -778,13 +869,22 @@ private long startTime = 0L;
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()
{ {
@ -797,8 +897,10 @@ private long startTime = 0L;
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;
if ( line.indexOf( "vfat" ) < 0 && line.indexOf( "/mnt" ) < 0 )
continue;
StringTokenizer tokens = new StringTokenizer( line, " " ); StringTokenizer tokens = new StringTokenizer( line, " " );
tokens.nextToken(); tokens.nextToken();
String d = tokens.nextToken(); String d = tokens.nextToken();
@ -806,7 +908,8 @@ private long startTime = 0L;
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[]
{ "/mnt/secure", "/mnt/asec", "/mnt/obb", "/dev/mapper", "tmpfs", "/mnt/media_rw" };
for ( String v : vetos ) 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 )
@ -25,10 +21,22 @@ public class ConfigHelper
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)
{
}
}
} }
} }
@ -42,10 +50,15 @@ public class ConfigHelper
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;
} }
@ -131,6 +174,7 @@ public abstract class CoordinateReader
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 CoordinateReaderOsmAnd( base3, true ) );
rl.add( new CoordinateReaderLocus( base3 ) ); rl.add( new CoordinateReaderLocus( base3 ) );
rl.add( new CoordinateReaderOrux( base3 ) ); rl.add( new CoordinateReaderOrux( base3 ) );
} }

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,28 +1,16 @@
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 };
@ -32,317 +20,84 @@ public class Raster2Png extends Object {
/** 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 );
bytesPerPixel = (encodeAlpha) ? 4 : 3;
Deflater scrunch = new Deflater(compressionLevel);
ByteArrayOutputStream outBytes = new ByteArrayOutputStream( 1024 ); ByteArrayOutputStream outBytes = new ByteArrayOutputStream( 1024 );
DeflaterOutputStream compBytes = new DeflaterOutputStream( outBytes, scrunch ); DeflaterOutputStream compBytes = new DeflaterOutputStream( outBytes, scrunch );
try { while (rowsLeft > 0)
while (rowsLeft > 0) { {
nRows = Math.min( 32767 / ( width * ( bytesPerPixel + 1 ) ), rowsLeft ); nRows = Math.min( 32767 / ( width * ( bytesPerPixel + 1 ) ), rowsLeft );
nRows = Math.max( nRows, 1 ); nRows = Math.max( nRows, 1 );
@ -351,39 +106,20 @@ public class Raster2Png extends Object {
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] >> 16 ) & 0xff );
scanLines[scanPos++] = (byte) ( ( pixels[i] >> 8 ) & 0xff ); scanLines[scanPos++] = (byte) ( ( pixels[i] >> 8 ) & 0xff );
scanLines[scanPos++] = (byte) ( ( pixels[i] ) & 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);
}
}
} }
/* /*
@ -403,33 +139,21 @@ 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 )
@ -443,22 +167,4 @@ public class Raster2Png extends Object {
} }
} }
} }
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;
}
} }