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: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( " 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( " <name>" ).append( name ).append( "</name>\n" );
sb.append( " <trkseg>\n" );

View file

@ -236,7 +236,12 @@ public class RoutingEngine extends Thread
{
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;
findTrack( "seededSearch", seedPoint, null, null, null, false );

View file

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

View file

@ -9,146 +9,146 @@ import btools.util.Raster2Png;
public class TrafficData2Png
{
private static int minLon;
private static int minLat;
private static int maxLon;
private static int maxLat;
private static int ncols;
private static int nrows;
private static int[] pixels;
private static int minLon;
private static int minLat;
private static int maxLon;
private static int maxLat;
private static int ncols;
private static int nrows;
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],
Double.parseDouble( args[2] ), Double.parseDouble( args[3] ), Double.parseDouble( args[4] ), Double.parseDouble( args[5] ),
Integer.parseInt( args[6] ), Integer.parseInt( args[7] ) );
}
else if ( args.length == 4 )
{
int lon0 = Integer.parseInt( args[0] );
int lat0 = Integer.parseInt( args[1] );
String inputFile = "traffic/E" + lon0 + "_N" + lat0 + ".trf";
for( int lon = lon0; lon < lon0+5; lon++ )
for( int lat = lat0; lat < lat0+5; lat++ )
{
String imageFile = "traffic_pics/E" + lon + "_N" + lat + ".png";
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( args[0], args[1], Double.parseDouble( args[2] ), Double.parseDouble( args[3] ), Double.parseDouble( args[4] ),
Double.parseDouble( args[5] ), Integer.parseInt( args[6] ), Integer.parseInt( args[7] ) );
}
else if ( args.length == 4 )
{
int lon0 = Integer.parseInt( args[0] );
int lat0 = Integer.parseInt( args[1] );
String inputFile = "traffic/E" + lon0 + "_N" + lat0 + ".trf";
for ( int lon = lon0; lon < lon0 + 5; lon++ )
for ( int lat = lat0; lat < lat0 + 5; lat++ )
{
String imageFile = "traffic_pics/E" + lon + "_N" + lat + ".png";
System.out.println( "file=" + inputFile + " image=" + imageFile );
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,
int cols, int rows ) throws Exception
}
public static void doConvert( String inputFile, String imageFile, double lon0, double lat0, double lon1, double lat1, int cols, int rows )
throws Exception
{
OsmTrafficMap trafficMap = new OsmTrafficMap();
minLon = (int) ( lon0 * 1000000 + 180000000 );
maxLon = (int) ( lon1 * 1000000 + 180000000 );
minLat = (int) ( lat0 * 1000000 + 90000000 );
maxLat = (int) ( lat1 * 1000000 + 90000000 );
ncols = cols;
nrows = rows;
long[] keys = trafficMap.load( new File( inputFile ), minLon, minLat, maxLon, maxLat, true );
pixels = new int[cols * rows];
int[] tclasses = new int[]
{ 1, 2, 3, 4, 5, 6, 7, -1 };
for ( int tclass : tclasses )
{
OsmTrafficMap trafficMap = new OsmTrafficMap();
minLon = (int)(lon0 * 1000000 + 180000000);
maxLon = (int)(lon1 * 1000000 + 180000000);
minLat = (int)(lat0 * 1000000 + 90000000);
maxLat = (int)(lat1 * 1000000 + 90000000);
ncols = cols;
nrows = rows;
long[] keys = trafficMap.load( new File( inputFile ), minLon, minLat, maxLon, maxLat, true );
pixels = new int[cols*rows];
int[] tclasses = new int[] { 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 );
while (e != null)
{
OsmTrafficMap.OsmTrafficElement e = trafficMap.getElement(key );
while( e != null )
long key2 = e.node2;
e = e.next;
int trafficClass = trafficMap.getTrafficClass( key, key2 );
if ( trafficClass != tclass )
continue;
int[] from = getImagePosition( key );
int[] to = getImagePosition( key2 );
int rgb = 0;
if ( trafficClass == -1 ) rgb = 0x0000ff; // blue
else if ( trafficClass == 1 ) rgb = 0x404040; // dark grey
else if ( trafficClass == 2 ) rgb = 0xa0a0a0; // light grey
else if ( trafficClass == 3 ) rgb = 0x00ff00; // green
else if ( trafficClass == 4 ) rgb = 0xf4e500; // yellow
else if ( trafficClass == 5 ) rgb = 0xf18e1c; // orange
else if ( trafficClass == 6 ) rgb = 0xe32322; // red
else if ( trafficClass == 7 ) rgb = 0xc0327d; // pink
if ( rgb != 0 )
{
long key2 = e.node2;
e = e.next;
int trafficClass = trafficMap.getTrafficClass( key, key2 );
if ( trafficClass != tclass ) continue;
int[] from = getImagePosition( key );
int[] to = getImagePosition( key2 );
int rgb = 0;
if ( trafficClass == -1 ) rgb = 0x0000ff; // blue
else if ( trafficClass == 1 ) rgb = 0x404040; // dark grey
else if ( trafficClass == 2 ) rgb = 0xa0a0a0; // light grey
else if ( trafficClass == 3 ) rgb = 0x00ff00; // green
else if ( trafficClass == 4 ) rgb = 0xf4e500; // yellow
else if ( trafficClass == 5 ) rgb = 0xf18e1c; // orange
else if ( trafficClass == 6 ) rgb = 0xe32322; // red
else if ( trafficClass == 7 ) rgb = 0xc0327d; // pink
if ( rgb != 0 )
{
drawLine( from, to, rgb );
}
drawLine( from, to, rgb );
}
}
}
Raster2Png r2p = new Raster2Png( Raster2Png.FILTER_NONE, 6, cols, rows, pixels );
byte[] png = r2p.pngEncode( );
System.out.println( "got png of size: " + png.length );
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( imageFile ) ) );
dos.write(png);
dos.close();
}
private static void drawLine( int[] from, int[] to, int rgb )
byte[] png = new Raster2Png().pngEncode( cols, rows, pixels );
System.out.println( "got png of size: " + png.length );
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( imageFile ) ) );
dos.write( png );
dos.close();
}
private static void drawLine( int[] from, int[] to, int rgb )
{
int ix = from[0];
int iy = from[1];
int ixx = to[0];
int iyy = to[1];
int sx = ixx > ix ? 1 : -1;
int sy = iyy > iy ? 1 : -1;
int dx = ( ixx - ix ) * sx;
int dy = ( iyy - iy ) * sy;
int sum = 0;
for ( ;; )
{
int ix = from[0];
int iy = from[1];
int ixx = to[0];
int iyy = to[1];
drawPixel( ix, iy, rgb );
if ( ix == ixx && iy == iyy )
break;
int sx = ixx > ix ? 1 : -1;
int sy = iyy > iy ? 1 : -1;
int dx = (ixx-ix)*sx;
int dy = (iyy-iy)*sy;
int sum = 0;
for(;;)
if ( Math.abs( sum + dx ) < Math.abs( sum - dy ) )
{
drawPixel( ix, iy, rgb );
if ( ix == ixx && iy == iyy ) break;
if ( Math.abs( sum+dx ) < Math.abs( sum-dy ) )
{
iy+= sy;
sum += dx;
}
else
{
ix+= sx;
sum -= dy;
}
iy += sy;
sum += dx;
}
else
{
ix += sx;
sum -= dy;
}
}
}
private static void drawPixel( int ix, int iy, int rgb )
private static void drawPixel( int ix, int iy, int rgb )
{
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 )
{
int ilon = (int)(key >> 32);
int ilat = (int)(key & 0xffffffff);
double lonDelta = maxLon-minLon;
double latDelta = maxLat-minLat;
int[] res = new int[2];
res[0] = (int)( ( (ilon-minLon)/lonDelta ) *ncols );
res[1] = (int)( ( (ilat-minLat)/latDelta ) *nrows );
return res;
}
private static int[] getImagePosition( long key )
{
int ilon = (int) ( key >> 32 );
int ilat = (int) ( key & 0xffffffff );
double lonDelta = maxLon - minLon;
double latDelta = maxLat - minLat;
int[] res = new int[2];
res[0] = (int) ( ( ( ilon - minLon ) / lonDelta ) * ncols );
res[1] = (int) ( ( ( ilat - minLat ) / latDelta ) * nrows );
return res;
}
}

View file

@ -11,45 +11,52 @@ import java.io.FileReader;
public class StorageConfigHelper
{
public static File getSecondarySegmentDir( String segmentDir )
{
return getStorageLocation( segmentDir, "secondary_segment_dir=" );
}
public static File getSecondarySegmentDir( String segmentDir )
{
return getStorageLocation( segmentDir, "secondary_segment_dir=" );
}
public static File getAdditionalMaptoolDir( String segmentDir )
{
return getStorageLocation( segmentDir, "additional_maptool_dir=" );
}
public static File getAdditionalMaptoolDir( String segmentDir )
{
return getStorageLocation( segmentDir, "additional_maptool_dir=" );
}
private static File getStorageLocation( String segmentDir, String tag )
{
File res = null;
BufferedReader br = null;
String configFile = segmentDir + "/storageconfig.txt";
private static File getStorageLocation( String segmentDir, String tag )
{
File res = null;
BufferedReader br = null;
String configFile = segmentDir + "/storageconfig.txt";
try
{
br = new BufferedReader( new FileReader( configFile ) );
for ( ;; )
{
String line = br.readLine();
if ( line == null ) break;
line = line.trim();
if ( line.startsWith( "#" ) ) continue;
if ( line.startsWith( tag ) )
{
String path = line.substring( tag.length() ).trim();
res = path.startsWith( "/" ) ? new File( path ) : new File( new File( segmentDir ), path );
if ( !res.exists() ) res = null;
break;
}
}
}
catch (Exception e) { /* ignore */ }
finally
{
if ( br != null )
{
try
{
br = new BufferedReader( new FileReader (configFile ) );
for(;;)
{
String line = br.readLine();
if ( line == null ) break;
line = line.trim();
if ( line.startsWith( "#") ) continue;
if ( line.startsWith( tag ) )
{
String path = line.substring( tag.length() ).trim();
res = path.startsWith( "/" ) ? new File( path ) : new File( new File( segmentDir ) , path );
if ( !res.exists() ) res = null;
break;
}
}
br.close();
}
catch( Exception e ) {}
finally
{
if ( br != null ) try { br.close(); } catch( Exception ee ) {}
}
return res;
}
catch (Exception ee) { /* ignore */ }
}
}
return res;
}
}

View file

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

View file

@ -21,473 +21,494 @@ import android.speech.tts.TextToSpeech.OnInitListener;
import android.widget.EditText;
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_EXCEPTION_ID = 2;
private static final int DIALOG_SHOW_DM_INFO_ID = 3;
private static final int DIALOG_TEXTENTRY_ID = 4;
private static final int DIALOG_VIASELECT_ID = 5;
private static final int DIALOG_NOGOSELECT_ID = 6;
private static final int DIALOG_SHOWRESULT_ID = 7;
private static final int DIALOG_ROUTINGMODES_ID = 8;
private static final int DIALOG_MODECONFIGOVERVIEW_ID = 9;
private static final int DIALOG_PICKWAYPOINT_ID = 10;
private static final int DIALOG_SELECTBASEDIR_ID = 11;
private static final int DIALOG_MAINACTION_ID = 12;
private static final int DIALOG_OLDDATAHINT_ID = 13;
private static final int DIALOG_SELECTPROFILE_ID = 1;
private static final int DIALOG_EXCEPTION_ID = 2;
private static final int DIALOG_SHOW_DM_INFO_ID = 3;
private static final int DIALOG_TEXTENTRY_ID = 4;
private static final int DIALOG_VIASELECT_ID = 5;
private static final int DIALOG_NOGOSELECT_ID = 6;
private static final int DIALOG_SHOWRESULT_ID = 7;
private static final int DIALOG_ROUTINGMODES_ID = 8;
private static final int DIALOG_MODECONFIGOVERVIEW_ID = 9;
private static final int DIALOG_PICKWAYPOINT_ID = 10;
private static final int DIALOG_SELECTBASEDIR_ID = 11;
private static final int DIALOG_MAINACTION_ID = 12;
private static final int DIALOG_OLDDATAHINT_ID = 13;
private BRouterView mBRouterView;
private PowerManager mPowerManager;
private WakeLock mWakeLock;
private BRouterView mBRouterView;
private PowerManager mPowerManager;
private WakeLock mWakeLock;
/** Called when the activity is first created. */
@Override
@SuppressWarnings("deprecation")
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
/** Called when the activity is first created. */
@Override
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService( POWER_SERVICE );
// Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
// Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName() );
// Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
.getName());
// instantiate our simulation view and set it as the activity's content
mBRouterView = new BRouterView( this );
mBRouterView.init();
setContentView( mBRouterView );
}
// instantiate our simulation view and set it as the activity's content
mBRouterView = new BRouterView(this);
mBRouterView.init();
setContentView(mBRouterView);
}
@Override
@SuppressWarnings("deprecation")
protected Dialog onCreateDialog(int id)
@Override
@SuppressWarnings("deprecation")
protected Dialog onCreateDialog( int id )
{
AlertDialog.Builder builder;
switch ( id )
{
AlertDialog.Builder builder;
switch(id)
case DIALOG_SELECTPROFILE_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Select a routing profile" );
builder.setItems( availableProfiles, new DialogInterface.OnClickListener()
{
case DIALOG_SELECTPROFILE_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Select a routing profile");
builder.setItems(availableProfiles, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
selectedProfile = availableProfiles[item];
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
case DIALOG_MAINACTION_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Select Main Action");
builder.setItems( new String[] { "Download Manager", "BRouter App" }, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if ( item == 0 ) startDownloadManager();
else showDialog( DIALOG_SELECTPROFILE_ID );
}
});
return builder.create();
case DIALOG_SHOW_DM_INFO_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( "BRouter Download Manager" )
.setMessage( "*** Attention: ***\n\n"
+ "The Download Manager is used to download routing-data "
+ "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." )
.setPositiveButton( "I know", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class);
startActivity(intent);
finish();
}
})
.setNegativeButton( "Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_OLDDATAHINT_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( "Local setup needs reset" )
.setMessage( "You are currently using an old version of the lookup-table "
+ "together with routing data made for this old table. "
+ "Before downloading new datafiles made for the new table, "
+ "you have to reset your local setup by 'moving away' (or deleting) "
+ "your <basedir>/brouter directory and start a new setup by calling the "
+ "BRouter App again." )
.setPositiveButton( "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_ROUTINGMODES_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( message );
builder.setMultiChoiceItems(routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
routingModesChecked[which] = isChecked;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.configureService(routingModes,routingModesChecked);
}
});
return builder.create();
case DIALOG_EXCEPTION_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( "An Error occured" )
.setMessage( errorMessage )
.setPositiveButton( "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mBRouterView.continueProcessing();
}
});
return builder.create();
case DIALOG_TEXTENTRY_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Enter SDCARD base dir:");
builder.setMessage(message);
final EditText input = new EditText(this);
input.setText( defaultbasedir );
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String basedir = input.getText().toString();
mBRouterView.startSetup(basedir, true );
}
});
return builder.create();
case DIALOG_SELECTBASEDIR_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Select an SDCARD base dir:");
builder.setSingleChoiceItems(basedirOptions, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item )
{
selectedBasedir = item;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
if ( selectedBasedir < availableBasedirs.size() )
{
mBRouterView.startSetup(availableBasedirs.get(selectedBasedir), true );
}
else
{
showDialog( DIALOG_TEXTENTRY_ID );
}
}
});
return builder.create();
case DIALOG_VIASELECT_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Check VIA Selection:");
builder.setMultiChoiceItems(availableVias, getCheckedBooleanArray( availableVias.length ),
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
if (isChecked)
{
selectedVias.add(availableVias[which]);
}
else
{
selectedVias.remove(availableVias[which]);
}
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.updateViaList( selectedVias );
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
case DIALOG_NOGOSELECT_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle("Check NoGo Selection:");
String[] nogoNames = new String[nogoList.size()];
for( int i=0; i<nogoList.size(); i++ ) nogoNames[i] = nogoList.get(i).name;
final boolean[] nogoEnabled = getCheckedBooleanArray(nogoList.size());
builder.setMultiChoiceItems(nogoNames, getCheckedBooleanArray( nogoNames.length ),
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
nogoEnabled[which] = isChecked;
}
});
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mBRouterView.updateNogoList( nogoEnabled );
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? "Exit" : ( wpCount == 0 ? "Select from" : "Select to/via" );
String rightLabel = wpCount < 2 ? "Server-Mode" : "Calc Route";
builder = new AlertDialog.Builder(this);
builder.setTitle( title )
.setMessage( errorMessage )
.setPositiveButton( leftLabel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if ( wpCount < 0 ) finish();
else mBRouterView.pickWaypoints();
}
})
.setNegativeButton( rightLabel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if ( wpCount < 2 ) mBRouterView.startConfigureService();
else
{
mBRouterView.finishWaypointSelection();
mBRouterView.startProcessing(selectedProfile);
}
}
});
return builder.create();
case DIALOG_MODECONFIGOVERVIEW_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( "Success" )
.setMessage( message )
.setPositiveButton( "Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_PICKWAYPOINT_ID:
builder = new AlertDialog.Builder(this);
builder.setTitle( wpCount > 0 ? "Select to/via" : "Select from" );
builder.setItems(availableWaypoints, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
mBRouterView.updateWaypointList( availableWaypoints[item] );
mBRouterView.startProcessing(selectedProfile);
}
});
return builder.create();
default:
return null;
public void onClick( DialogInterface dialog, int item )
{
selectedProfile = availableProfiles[item];
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_MAINACTION_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Select Main Action" );
builder.setItems( new String[]
{ "Download Manager", "BRouter App" }, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int item )
{
if ( item == 0 )
startDownloadManager();
else
showDialog( DIALOG_SELECTPROFILE_ID );
}
} );
return builder.create();
case DIALOG_SHOW_DM_INFO_ID:
builder = new AlertDialog.Builder( this );
builder
.setTitle( "BRouter Download Manager" )
.setMessage(
"*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
+ "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." ).setPositiveButton( "I know", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
Intent intent = new Intent( BRouterActivity.this, BInstallerActivity.class );
startActivity( intent );
finish();
}
} ).setNegativeButton( "Cancel", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_OLDDATAHINT_ID:
builder = new AlertDialog.Builder( this );
builder
.setTitle( "Local setup needs reset" )
.setMessage(
"You are currently using an old version of the lookup-table " + "together with routing data made for this old table. "
+ "Before downloading new datafiles made for the new table, "
+ "you have to reset your local setup by 'moving away' (or deleting) "
+ "your <basedir>/brouter directory and start a new setup by calling the " + "BRouter App again." )
.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_ROUTINGMODES_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( message );
builder.setMultiChoiceItems( routingModes, routingModesChecked, new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
routingModesChecked[which] = isChecked;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.configureService( routingModes, routingModesChecked );
}
} );
return builder.create();
case DIALOG_EXCEPTION_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "An Error occured" ).setMessage( errorMessage ).setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
mBRouterView.continueProcessing();
}
} );
return builder.create();
case DIALOG_TEXTENTRY_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Enter SDCARD base dir:" );
builder.setMessage( message );
final EditText input = new EditText( this );
input.setText( defaultbasedir );
builder.setView( input );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
String basedir = input.getText().toString();
mBRouterView.startSetup( basedir, true );
}
} );
return builder.create();
case DIALOG_SELECTBASEDIR_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Select an SDCARD base dir:" );
builder.setSingleChoiceItems( basedirOptions, 0, new DialogInterface.OnClickListener()
{
@Override
public void onClick( DialogInterface dialog, int item )
{
selectedBasedir = item;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
if ( selectedBasedir < availableBasedirs.size() )
{
mBRouterView.startSetup( availableBasedirs.get( selectedBasedir ), true );
}
else
{
showDialog( DIALOG_TEXTENTRY_ID );
}
}
} );
return builder.create();
case DIALOG_VIASELECT_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Check VIA Selection:" );
builder.setMultiChoiceItems( availableVias, getCheckedBooleanArray( availableVias.length ), new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
if ( isChecked )
{
selectedVias.add( availableVias[which] );
}
else
{
selectedVias.remove( availableVias[which] );
}
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateViaList( selectedVias );
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_NOGOSELECT_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Check NoGo Selection:" );
String[] nogoNames = new String[nogoList.size()];
for ( int i = 0; i < nogoList.size(); i++ )
nogoNames[i] = nogoList.get( i ).name;
final boolean[] nogoEnabled = getCheckedBooleanArray( nogoList.size() );
builder.setMultiChoiceItems( nogoNames, getCheckedBooleanArray( nogoNames.length ), new DialogInterface.OnMultiChoiceClickListener()
{
@Override
public void onClick( DialogInterface dialog, int which, boolean isChecked )
{
nogoEnabled[which] = isChecked;
}
} );
builder.setPositiveButton( "Ok", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int whichButton )
{
mBRouterView.updateNogoList( nogoEnabled );
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? "Exit" : ( wpCount == 0 ? "Select from" : "Select to/via" );
String rightLabel = wpCount < 2 ? "Server-Mode" : "Calc Route";
builder = new AlertDialog.Builder( this );
builder.setTitle( title ).setMessage( errorMessage ).setPositiveButton( leftLabel, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
if ( wpCount < 0 )
finish();
else
mBRouterView.pickWaypoints();
}
} ).setNegativeButton( rightLabel, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
if ( wpCount < 2 )
mBRouterView.startConfigureService();
else
{
mBRouterView.finishWaypointSelection();
mBRouterView.startProcessing( selectedProfile );
}
}
} );
return builder.create();
case DIALOG_MODECONFIGOVERVIEW_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( "Success" ).setMessage( message ).setPositiveButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int id )
{
finish();
}
} );
return builder.create();
case DIALOG_PICKWAYPOINT_ID:
builder = new AlertDialog.Builder( this );
builder.setTitle( wpCount > 0 ? "Select to/via" : "Select from" );
builder.setItems( availableWaypoints, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int item )
{
mBRouterView.updateWaypointList( availableWaypoints[item] );
mBRouterView.startProcessing( selectedProfile );
}
} );
return builder.create();
default:
return null;
}
}
private boolean[] getCheckedBooleanArray( int size )
private boolean[] getCheckedBooleanArray( int size )
{
boolean[] checked = new boolean[size];
for ( int i = 0; i < checked.length; i++ ) checked[i] = true;
return checked;
}
private String[] availableProfiles;
private String selectedProfile = null;
private List<String> availableBasedirs;
private String[] basedirOptions;
private int selectedBasedir;
private String[] availableWaypoints;
private String[] routingModes;
private boolean[] routingModesChecked;
private String defaultbasedir = null;
private String message = null;
private String[] availableVias;
private Set<String> selectedVias;
private List<OsmNodeNamed> nogoList;
public boolean isOnline()
{
ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE );
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
@SuppressWarnings("deprecation")
public void selectProfile( String[] items )
{
availableProfiles = items;
// if we have internet access, first show the main action dialog
if ( isOnline() )
{
boolean[] checked = new boolean[size];
for( int i=0; i<checked.length; i++ ) checked[i] = true;
return checked;
showDialog( DIALOG_MAINACTION_ID );
}
private String[] availableProfiles;
private String selectedProfile = null;
private List<String> availableBasedirs;
private String[] basedirOptions;
private int selectedBasedir;
private String[] availableWaypoints;
private String[] routingModes;
private boolean[] routingModesChecked;
private String defaultbasedir = null;
private String message = null;
private String[] availableVias;
private Set<String> selectedVias;
private List<OsmNodeNamed> nogoList;
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
@SuppressWarnings("deprecation")
public void selectProfile( String[] items )
else
{
availableProfiles = items;
// if we have internet access, first show the main action dialog
if ( isOnline() )
{
showDialog( DIALOG_MAINACTION_ID );
}
else
{
showDialog( DIALOG_SELECTPROFILE_ID );
}
showDialog( DIALOG_SELECTPROFILE_ID );
}
}
@SuppressWarnings("deprecation")
public void startDownloadManager()
@SuppressWarnings("deprecation")
public void startDownloadManager()
{
if ( !mBRouterView.hasUpToDateLookups() )
{
if ( !mBRouterView.hasUpToDateLookups() )
{
showDialog( DIALOG_OLDDATAHINT_ID );
}
else
{
showDialog( DIALOG_SHOW_DM_INFO_ID );
}
showDialog( DIALOG_OLDDATAHINT_ID );
}
@SuppressWarnings("deprecation")
public void selectBasedir( List<String> items, String defaultBasedir, String message )
else
{
this.defaultbasedir = defaultBasedir;
this.message = message;
availableBasedirs = new ArrayList<String>();
ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
for( String d : items )
showDialog( DIALOG_SHOW_DM_INFO_ID );
}
}
@SuppressWarnings("deprecation")
public void selectBasedir( List<String> items, String defaultBasedir, String message )
{
this.defaultbasedir = defaultBasedir;
this.message = message;
availableBasedirs = new ArrayList<String>();
ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
for ( String d : items )
{
try
{
try
{
StatFs stat = new StatFs(d);
long size = (long)stat.getAvailableBlocks()*stat.getBlockSize();
StatFs stat = new StatFs( d );
long size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
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 );
dirFreeSizes.add( idx, Long.valueOf( size ) );
}
catch( Exception e ) { /* ignore */ }
}
basedirOptions= new String[items.size() + 1];
int bdidx = 0;
DecimalFormat df = new DecimalFormat( "###0.00" );
for( int idx=0; idx<availableBasedirs.size(); idx++ )
{
basedirOptions[bdidx++] = availableBasedirs.get(idx)
+ " (" + df.format( dirFreeSizes.get(idx)/1024./1024./1024. ) + " GB free)";
}
basedirOptions[bdidx] = "Other";
showDialog( DIALOG_SELECTBASEDIR_ID );
catch (Exception e) { /* ignore */ }
}
@SuppressWarnings("deprecation")
public void selectRoutingModes( String[] modes, boolean[] modesChecked, String message )
basedirOptions = new String[items.size() + 1];
int bdidx = 0;
DecimalFormat df = new DecimalFormat( "###0.00" );
for ( int idx = 0; idx < availableBasedirs.size(); idx++ )
{
routingModes = modes;
routingModesChecked = modesChecked;
this.message = message;
showDialog( DIALOG_ROUTINGMODES_ID );
basedirOptions[bdidx++] = availableBasedirs.get( idx ) + " (" + df.format( dirFreeSizes.get( idx ) / 1024. / 1024. / 1024. ) + " GB free)";
}
basedirOptions[bdidx] = "Other";
@SuppressWarnings("deprecation")
public void showModeConfigOverview( String message )
showDialog( DIALOG_SELECTBASEDIR_ID );
}
@SuppressWarnings("deprecation")
public void selectRoutingModes( String[] modes, boolean[] modesChecked, String message )
{
routingModes = modes;
routingModesChecked = modesChecked;
this.message = message;
showDialog( DIALOG_ROUTINGMODES_ID );
}
@SuppressWarnings("deprecation")
public void showModeConfigOverview( String message )
{
this.message = message;
showDialog( DIALOG_MODECONFIGOVERVIEW_ID );
}
@SuppressWarnings("deprecation")
public void selectVias( String[] items )
{
availableVias = items;
selectedVias = new HashSet<String>( availableVias.length );
for ( String via : items )
selectedVias.add( via );
showDialog( DIALOG_VIASELECT_ID );
}
@SuppressWarnings("deprecation")
public void selectWaypoint( String[] items )
{
availableWaypoints = items;
showNewDialog( DIALOG_PICKWAYPOINT_ID );
}
@SuppressWarnings("deprecation")
public void selectNogos( List<OsmNodeNamed> nogoList )
{
this.nogoList = nogoList;
showDialog( DIALOG_NOGOSELECT_ID );
}
private Set<Integer> dialogIds = new HashSet<Integer>();
private void showNewDialog( int id )
{
if ( dialogIds.contains( Integer.valueOf( id ) ) )
{
this.message = message;
showDialog( DIALOG_MODECONFIGOVERVIEW_ID );
removeDialog( id );
}
dialogIds.add( Integer.valueOf( id ) );
showDialog( id );
}
private String errorMessage;
private String title;
private int wpCount;
@SuppressWarnings("deprecation")
public void selectVias( String[] items )
{
availableVias = items;
selectedVias = new HashSet<String>(availableVias.length);
for( String via : items ) selectedVias.add( via );
showDialog( DIALOG_VIASELECT_ID );
}
@SuppressWarnings("deprecation")
public void showErrorMessage( String msg )
{
errorMessage = msg;
showNewDialog( DIALOG_EXCEPTION_ID );
}
@SuppressWarnings("deprecation")
public void selectWaypoint( String[] items )
{
availableWaypoints = items;
showNewDialog( DIALOG_PICKWAYPOINT_ID );
}
@SuppressWarnings("deprecation")
public void showResultMessage( String title, String msg, int wpCount )
{
errorMessage = msg;
this.title = title;
this.wpCount = wpCount;
showNewDialog( DIALOG_SHOWRESULT_ID );
}
@SuppressWarnings("deprecation")
public void selectNogos( List<OsmNodeNamed> nogoList )
{
this.nogoList = nogoList;
showDialog( DIALOG_NOGOSELECT_ID );
}
@Override
protected void onResume()
{
super.onResume();
/*
* when the activity is resumed, we acquire a wake-lock so that the screen
* stays on, since the user will likely not be fiddling with the screen or
* buttons.
*/
mWakeLock.acquire();
}
private Set<Integer> dialogIds = new HashSet<Integer>();
@Override
protected void onPause()
{
super.onPause();
/*
* When the activity is paused, we make sure to stop the router
*/
private void showNewDialog( int id )
{
if ( dialogIds.contains( Integer.valueOf( id ) ) )
{
removeDialog( id );
}
dialogIds.add( Integer.valueOf( id ) );
showDialog( id );
}
// Stop the simulation
mBRouterView.stopRouting();
private String errorMessage;
private String title;
private int wpCount;
@SuppressWarnings("deprecation")
public void showErrorMessage( String msg )
{
errorMessage = msg;
showNewDialog( DIALOG_EXCEPTION_ID );
}
@SuppressWarnings("deprecation")
public void showResultMessage( String title, String msg, int wpCount )
{
errorMessage = msg;
this.title = title;
this.wpCount = wpCount;
showNewDialog( DIALOG_SHOWRESULT_ID );
}
@Override
protected void onResume() {
super.onResume();
/*
* when the activity is resumed, we acquire a wake-lock so that the
* screen stays on, since the user will likely not be fiddling with the
* screen or buttons.
*/
mWakeLock.acquire();
// Start the simulation
mBRouterView.startSimulation();
}
@Override
protected void onPause() {
super.onPause();
/*
* When the activity is paused, we make sure to stop the simulation,
* release our sensor resources and wake locks
*/
// Stop the simulation
mBRouterView.stopSimulation();
// and release our wake-lock
mWakeLock.release();
}
@Override
public void onInit(int i)
{
}
// and release our wake-lock
mWakeLock.release();
}
@Override
public void onInit( int i )
{
}
}

View file

@ -9,43 +9,56 @@ import java.io.OutputStreamWriter;
import android.content.Context;
/**
* Decsription of a service config
*/
public class ConfigHelper
{
public static String getBaseDir( Context ctx )
{
// get base dir from private file
InputStream configInput = null;
try
{
configInput = ctx.openFileInput( "config.dat" );
BufferedReader br = new BufferedReader( new InputStreamReader (configInput ) );
return br.readLine();
}
catch( Exception e ) { return null; }
finally
{
if ( configInput != null ) try { configInput.close(); } catch( Exception ee ) {}
}
}
public static String getBaseDir( Context ctx )
{
// get base dir from private file
InputStream configInput = null;
try
{
configInput = ctx.openFileInput( "config.dat" );
BufferedReader br = new BufferedReader( new InputStreamReader( configInput ) );
return br.readLine();
}
catch (Exception e)
{
return null;
}
finally
{
if ( configInput != null )
{
try
{
configInput.close();
}
catch (Exception ee)
{
}
}
}
}
public static void writeBaseDir( Context ctx, String baseDir )
{
BufferedWriter bw = null;
try
{
OutputStream configOutput = ctx.openFileOutput( "config.dat", Context.MODE_PRIVATE );
bw = new BufferedWriter( new OutputStreamWriter (configOutput ) );
bw.write( baseDir );
bw.write( '\n' );
}
catch( Exception e ) {}
finally
{
if ( bw != null ) try { bw.close(); } catch( Exception ee ) {}
}
}
public static void writeBaseDir( Context ctx, String baseDir )
{
BufferedWriter bw = null;
try
{
OutputStream configOutput = ctx.openFileOutput( "config.dat", Context.MODE_PRIVATE );
bw = new BufferedWriter( new OutputStreamWriter( configOutput ) );
bw.write( baseDir );
bw.write( '\n' );
}
catch (Exception e){ /* ignore */ }
finally
{
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.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.os.Environment;
import btools.router.OsmNodeNamed;
@ -22,7 +25,9 @@ public abstract class CoordinateReader
public String rootdir;
public String tracksdir;
public Map<String,OsmNodeNamed> allpoints;
private Map<String,Map<String, OsmNodeNamed>> allpointsMap;
public List<OsmNodeNamed> allpoints;
private HashMap<String,OsmNodeNamed> pointmap;
protected static String[] posnames
@ -35,6 +40,34 @@ public abstract class CoordinateReader
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
*/
@ -62,13 +95,23 @@ public abstract class CoordinateReader
if ( fromToMissing ) waypoints.clear();
}
protected void checkAddPoint( OsmNodeNamed n )
protected void checkAddPoint( String category, OsmNodeNamed n )
{
if ( allpoints != null )
{
allpoints.put( n.name, n );
return;
}
if ( allpointsMap != null )
{
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;
}
boolean isKnown = false;
for( int i=0; i<posnames.length; i++ )
@ -100,70 +143,71 @@ public abstract class CoordinateReader
public static CoordinateReader obtainValidReader( String basedir, String segmentDir ) throws Exception
{
CoordinateReader cor = null;
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
CoordinateReader cor = null;
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
AppLogger.log( "adding standard maptool-base: " + basedir );
rl.add( new CoordinateReaderOsmAnd(basedir) );
rl.add( new CoordinateReaderLocus(basedir) );
rl.add( new CoordinateReaderOrux(basedir) );
AppLogger.log( "adding standard maptool-base: " + basedir );
rl.add( new CoordinateReaderOsmAnd( basedir ) );
rl.add( new CoordinateReaderLocus( basedir ) );
rl.add( new CoordinateReaderOrux( basedir ) );
// eventually add standard-sd
File standardbase = Environment.getExternalStorageDirectory();
if ( standardbase != null )
{
String base2 = standardbase.getAbsolutePath();
if ( !base2.equals( basedir ) )
{
AppLogger.log( "adding internal sd maptool-base: " + base2 );
rl.add( new CoordinateReaderOsmAnd(base2) );
rl.add( new CoordinateReaderLocus(base2) );
rl.add( new CoordinateReaderOrux(base2) );
}
}
// eventually add standard-sd
File standardbase = Environment.getExternalStorageDirectory();
if ( standardbase != null )
{
String base2 = standardbase.getAbsolutePath();
if ( !base2.equals( basedir ) )
{
AppLogger.log( "adding internal sd maptool-base: " + base2 );
rl.add( new CoordinateReaderOsmAnd( base2 ) );
rl.add( new CoordinateReaderLocus( base2 ) );
rl.add( new CoordinateReaderOrux( base2 ) );
}
}
// eventually add explicit directory
File additional = RoutingHelper.getAdditionalMaptoolDir(segmentDir);
if ( additional != null )
{
String base3 = additional.getAbsolutePath();
// eventually add explicit directory
File additional = RoutingHelper.getAdditionalMaptoolDir( segmentDir );
if ( additional != null )
{
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 CoordinateReaderLocus(base3) );
rl.add( new CoordinateReaderOrux(base3) );
}
rl.add( new CoordinateReaderOsmAnd( base3 ) );
rl.add( new CoordinateReaderOsmAnd( base3, true ) );
rl.add( new CoordinateReaderLocus( base3 ) );
rl.add( new CoordinateReaderOrux( base3 ) );
}
long tmax = 0;
for( CoordinateReader r : rl )
{
if ( AppLogger.isLogging() )
{
AppLogger.log( "reading timestamp at systime " + new Date() );
}
long tmax = 0;
for ( CoordinateReader r : rl )
{
if ( AppLogger.isLogging() )
{
AppLogger.log( "reading timestamp at systime " + new Date() );
}
long t = r.getTimeStamp();
long t = r.getTimeStamp();
if ( t != 0 )
{
if ( AppLogger.isLogging() )
{
AppLogger.log( "found coordinate source at " + r.basedir + r.rootdir + " with timestamp " + new Date( t ) );
}
}
if ( t != 0 )
{
if ( AppLogger.isLogging() )
{
AppLogger.log( "found coordinate source at " + r.basedir + r.rootdir + " with timestamp " + new Date( t ) );
}
}
if ( t > tmax )
{
tmax = t;
cor = r;
}
}
if ( cor == null )
{
cor = new CoordinateReaderNone();
}
cor.readFromTo();
return cor;
if ( t > tmax )
{
tmax = t;
cor = r;
}
}
if ( cor == null )
{
cor = new CoordinateReaderNone();
}
cor.readFromTo();
return cor;
}
}

View file

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

View file

@ -38,14 +38,15 @@ public class CoordinateReaderOrux extends CoordinateReader
private void _readPointmap( String filename ) throws Exception
{
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())
{
OsmNodeNamed n = new OsmNodeNamed();
n.name = c.getString(0);
n.ilon = (int)( ( Double.parseDouble( c.getString(1) ) + 180. )*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();
}

View file

@ -12,18 +12,35 @@ import btools.router.OsmNodeNamed;
*/
public class CoordinateReaderOsmAnd extends CoordinateReader
{
private String osmandDir;
public CoordinateReaderOsmAnd( String basedir )
{
this( basedir, false );
}
public CoordinateReaderOsmAnd( String basedir, boolean shortPath )
{
super( basedir );
tracksdir = "/osmand/tracks";
rootdir = "/osmand";
if ( shortPath )
{
osmandDir = basedir;
tracksdir = "/tracks";
rootdir = "";
}
else
{
osmandDir = basedir + "/osmand";
tracksdir = "/osmand/tracks";
rootdir = "/osmand";
}
}
@Override
public long getTimeStamp() throws Exception
{
long t1 = new File( basedir + "/osmand/favourites_bak.gpx" ).lastModified();
long t2 = new File( basedir + "/osmand/favourites.gpx" ).lastModified();
long t1 = new File( osmandDir + "/favourites_bak.gpx" ).lastModified();
long t2 = new File( osmandDir + "/favourites.gpx" ).lastModified();
return t1 > t2 ? t1 : t2;
}
@ -36,11 +53,11 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
{
try
{
_readPointmap( basedir + "/osmand/favourites_bak.gpx" );
_readPointmap( osmandDir + "/favourites_bak.gpx" );
}
catch( Exception e )
{
_readPointmap( basedir + "/osmand/favourites.gpx" );
_readPointmap( osmandDir + "/favourites.gpx" );
}
}
@ -78,7 +95,7 @@ public class CoordinateReaderOsmAnd extends CoordinateReader
if ( idx11 >= 0 )
{
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.out.println("BRouter 1.3.1 / 18102015 / abrensch");
System.out.println("BRouter 1.3.2 / 31102015 / abrensch");
if ( args.length < 6 )
{
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
{
System.out.println("BRouter 1.3.1 / 18102015");
System.out.println("BRouter 1.3.2 / 31102015");
if ( args.length != 5 )
{
System.out.println("serve BRouter protocol");

View file

@ -1,464 +1,170 @@
package btools.util;
import java.io.*;
import java.util.zip.*;
public class Raster2Png extends Object {
/** 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;
/** Constants for filter (NONE) */
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. */
protected static final byte IHDR[] = {73, 72, 68, 82};
/** IDAT tag. */
protected static final byte IDAT[] = {73, 68, 65, 84};
/** IEND tag. */
protected static final byte IEND[] = {73, 69, 78, 68};
/** The png bytes. */
protected byte[] pngBytes;
/** The prior row. */
protected byte[] priorRow;
/** The left bytes. */
protected byte[] leftBytes;
/** The width. */
protected int width, height;
/** The byte position. */
protected int bytePos, maxPos;
protected int[] imagePixels;
/** CRC. */
protected CRC32 crc = new CRC32();
/** The CRC value. */
protected long crcValue;
/** 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.
*
* @param whichFilter 0=none, 1=sub, 2=up
* @param compLevel 0..9
*/
public Raster2Png(int whichFilter, int compLevel, int width, int height, int[] imagePixels ) {
this.width = width;
this.height = height;
this.imagePixels = imagePixels;
setFilter(whichFilter);
if (compLevel >= 0 && compLevel <= 9) {
this.compressionLevel = compLevel;
}
}
/**
* 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();
//dataPos = bytePos;
if (writeImageData()) {
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.
*/
protected void writeHeader() {
int startPos;
startPos = bytePos = writeInt4(13, bytePos);
bytePos = writeBytes(IHDR, bytePos);
bytePos = writeInt4(width, bytePos);
bytePos = writeInt4(height, bytePos);
bytePos = writeByte(8, bytePos); // bit depth
bytePos = writeByte((encodeAlpha) ? 6 : 2, bytePos); // direct model
bytePos = writeByte(0, bytePos); // compression method
bytePos = writeByte(0, bytePos); // filter method
bytePos = writeByte(0, bytePos); // no interlace
crc.reset();
crc.update(pngBytes, startPos, bytePos - startPos);
crcValue = crc.getValue();
bytePos = writeInt4((int) crcValue, bytePos);
}
/**
* Perform "sub" filtering on the given row.
* Uses temporary array leftBytes to store the original values
* of the previous pixels. The array is 16 bytes long, which
* 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) {
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 startRow = 0; // starting row to process this time through
int nRows; // how many rows to grab at a time
byte[] scanLines; // the scan lines to be compressed
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
int nCompressed; // how big is the compressed area?
//int depth; // color depth ( handle only 8 or 32 )
// PixelGrabber pg;
bytesPerPixel = (encodeAlpha) ? 4 : 3;
Deflater scrunch = new Deflater(compressionLevel);
ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
try {
while (rowsLeft > 0) {
nRows = Math.min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
nRows = Math.max( nRows, 1 );
int[] pixels = new int[width * nRows];
getPixels(startRow, nRows, pixels);
/*
* Create a data chunk. scanLines adds "nRows" for
* the filter bytes.
*/
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;
startPos = 1;
for (int i = 0; i < width * nRows; i++) {
if (i % width == 0) {
scanLines[scanPos++] = (byte) filter;
startPos = scanPos;
}
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);
}
}
}
/*
* Write these lines to the output area
*/
compBytes.write(scanLines, 0, scanPos);
startRow += nRows;
rowsLeft -= nRows;
}
compBytes.close();
/*
* Write the compressed bytes
*/
compressedLines = outBytes.toByteArray();
nCompressed = compressedLines.length;
crc.reset();
bytePos = writeInt4(nCompressed, bytePos);
bytePos = writeBytes(IDAT, bytePos);
crc.update(IDAT);
bytePos = writeBytes(compressedLines, nCompressed, bytePos);
crc.update(compressedLines, 0, nCompressed);
crcValue = crc.getValue();
bytePos = writeInt4((int) crcValue, bytePos);
scrunch.finish();
return true;
}
catch (IOException e) {
System.err.println(e.toString());
return false;
}
}
/**
* Write a PNG "IEND" chunk into the pngBytes array.
*/
protected void writeEnd() {
bytePos = writeInt4(0, bytePos);
bytePos = writeBytes(IEND, bytePos);
crc.reset();
crc.update(IEND);
crcValue = crc.getValue();
bytePos = writeInt4((int) crcValue, bytePos);
}
private void getPixels( int startRow, int nRows, int[] pixels)
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
public class Raster2Png extends ByteDataWriter
{
/** Constants for filter (NONE) */
public static final int FILTER_NONE = 0;
/** IHDR tag. */
protected static final byte IHDR[] = { 73, 72, 68, 82 };
/** IDAT tag. */
protected static final byte IDAT[] = { 73, 68, 65, 84 };
/** IEND tag. */
protected static final byte IEND[] = { 73, 69, 78, 68 };
/** geometry */
protected int width, height;
protected int[] imagePixels;
/** CRC. */
protected CRC32 crc = new CRC32();
public Raster2Png()
{
super( null );
}
/**
* Converts a pixel array to it's PNG equivalent
*/
public byte[] pngEncode( int width, int height, int[] imagePixels ) throws IOException
{
this.width = width;
this.height = height;
this.imagePixels = imagePixels;
// user a buffer large enough to hold the png
ab = new byte[( ( width + 1 ) * height * 3 ) + 200];
byte[] pngIdBytes =
{ -119, 80, 78, 71, 13, 10, 26, 10 };
write( pngIdBytes );
writeHeader();
writeImageData();
return toByteArray();
}
/**
* Write a PNG "IHDR" chunk into the pngBytes array.
*/
protected void writeHeader()
{
writeInt( 13 );
int startPos = aboffset;
write( IHDR );
writeInt( width );
writeInt( height );
writeByte( 8 ); // bit depth
writeByte( 2 ); // direct model
writeByte( 0 ); // compression method
writeByte( 0 ); // filter method
writeByte( 0 ); // no interlace
crc.reset();
crc.update( ab, startPos, aboffset - startPos );
writeInt( (int) crc.getValue() );
}
/**
* 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.
*/
protected void writeImageData() throws IOException
{
int rowsLeft = height; // number of rows remaining to write
int startRow = 0; // starting row to process this time through
int nRows; // how many rows to grab at a time
byte[] scanLines; // the scan lines to be compressed
int scanPos; // where we are in the scan lines
byte[] compressedLines; // the resultant compressed lines
int nCompressed; // how big is the compressed area?
int bytesPerPixel = 3;
Deflater scrunch = new Deflater( 6 );
ByteArrayOutputStream outBytes = new ByteArrayOutputStream( 1024 );
DeflaterOutputStream compBytes = new DeflaterOutputStream( outBytes, scrunch );
while (rowsLeft > 0)
{
for( int i=0; i<nRows; i++ )
{
int ir = i + startRow;
for( int ic=0; ic<width; ic++ )
{
pixels[ i*width + ic ] = imagePixels[ ir*width + ic];
}
}
}
nRows = Math.min( 32767 / ( width * ( bytesPerPixel + 1 ) ), rowsLeft );
nRows = Math.max( nRows, 1 );
private int pseudoLog( short sval )
int[] pixels = new int[width * nRows];
getPixels( startRow, nRows, pixels );
/*
* Create a data chunk. scanLines adds "nRows" for the filter bytes.
*/
scanLines = new byte[width * nRows * bytesPerPixel + nRows];
scanPos = 0;
for ( int i = 0; i < width * nRows; i++ )
{
if ( i % width == 0 )
{
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 );
}
/*
* Write these lines to the output area
*/
compBytes.write( scanLines, 0, scanPos );
startRow += nRows;
rowsLeft -= nRows;
}
compBytes.close();
/*
* Write the compressed bytes
*/
compressedLines = outBytes.toByteArray();
nCompressed = compressedLines.length;
crc.reset();
writeInt( nCompressed );
write( IDAT );
crc.update( IDAT );
write( compressedLines );
crc.update( compressedLines, 0, nCompressed );
writeInt( (int) crc.getValue() );
scrunch.finish();
// Write a PNG "IEND" chunk into the pngBytes array.
writeInt( 0 );
write( IEND );
crc.reset();
crc.update( IEND );
writeInt( (int) crc.getValue() );
}
private void getPixels( int startRow, int nRows, int[] pixels )
{
for ( int i = 0; i < nRows; i++ )
{
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;
int ir = i + startRow;
for ( int ic = 0; ic < width; ic++ )
{
pixels[i * width + ic] = imagePixels[ir * width + ic];
}
}
}
}