Merge pull request #439 from zod/remove-coordinate-readers

Remove coordinate readers

Sorry for the delay I didn't recognize the ready sign.
This commit is contained in:
afischerdev 2022-06-26 15:25:20 +02:00 committed by GitHub
commit 9d37e2c648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 492 additions and 1181 deletions

View file

@ -63,6 +63,7 @@ public class RoutingEngine extends Thread
private Object[] extract;
private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" );
private String outfile;
public RoutingEngine( String outfileBase, String logfileBase, File segmentDir,
List<OsmNodeNamed> waypoints, RoutingContext rc )
@ -185,6 +186,7 @@ public class RoutingEngine extends Thread
track.writeGpx( filename );
foundTrack = track;
alternativeIndex = i;
outfile = filename;
}
else
{
@ -1369,4 +1371,7 @@ public class RoutingEngine extends Thread
return terminated;
}
public String getOutfile() {
return outfile;
}
}

View file

@ -17,6 +17,7 @@ android {
setProperty("archivesBaseName", "BRouterApp." + defaultConfig.versionName)
minSdkVersion 14
targetSdkVersion 30
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -73,21 +74,6 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions "api"
productFlavors {
api19 {
dimension "api"
targetSdkVersion 19
}
api30 {
dimension "api"
targetSdkVersion 30
}
}
applicationVariants.all {
variant ->
{

View file

@ -0,0 +1,82 @@
package btools.routingapp;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.FileWriter;
public class CoordinateReaderTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void readNogoRoute() throws Exception {
File importFolder = temporaryFolder.newFolder("brouter", "import", "tracks");
File tempFile = new File(importFolder, "nogo_test.gpx");
try (FileWriter writer = new FileWriter(tempFile)) {
writer.write("<?xml version=\"1.0\"?>\n" +
"<gpx version=\"1.1\"\n" +
"creator=\"Viking 1.9 -- http://viking.sf.net/\"\n" +
"xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" xmlns:wptx1=\"http://www.garmin.com/xmlschemas/WaypointExtension/v1\" xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v2\" xmlns:gpxpx=\"http://www.garmin.com/xmlschemas/PowerExtension/v1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd\">\n" +
" <name>Nogo Route</name>\n" +
" <metadata>\n" +
" </metadata>\n" +
"<rte>\n" +
" <name>Nogo Oststadt</name>\n" +
" <extensions><gpxx:TrackExtension><gpxx:DisplayColor>Red</gpxx:DisplayColor></gpxx:TrackExtension></extensions>\n" +
" <rtept lat=\"49.009516920259095\" lon=\"8.423623305130004\">\n" +
" </rtept>\n" +
" <rtept lat=\"49.01034732709107\" lon=\"8.434330683517455\">\n" +
" </rtept>\n" +
" <rtept lat=\"49.01247254251079\" lon=\"8.445338469314574\">\n" +
" </rtept>\n" +
"</rte>\n" +
"</gpx>");
}
CoordinateReader coordinateReader = CoordinateReader.obtainValidReader(temporaryFolder.getRoot().getAbsolutePath(), false);
assertThat(coordinateReader.nogopoints, hasSize(1));
// Name should return "Nogo Oststadt", "Nogo Route" or "nogo_test.gpx"
assertThat(coordinateReader.nogopoints.get(0).name, equalTo("nogo_test"));
assertThat(coordinateReader.nogopoints.get(0).radius, closeTo(810.0, 5.0));
}
@Test
public void readWaypoints() throws Exception {
File importFolder = temporaryFolder.newFolder("brouter", "import");
File tempFile = new File(importFolder, "favourites.gpx");
try (FileWriter writer = new FileWriter(tempFile)) {
// https://en.wikipedia.org/wiki/GPS_Exchange_Format#Sample_GPX_document
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<gpx\n" +
" version=\"1.1\"\n" +
" creator=\"Runkeeper - http://www.runkeeper.com\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\"\n" +
" xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\">\n" +
"<wpt lat=\"37.778259000\" lon=\"-122.391386000\"><ele>3.4</ele><time>2016-06-17T23:41:03Z</time><name>from</name></wpt>\n" +
"<wpt lat=\"37.778194000\" lon=\"-122.391226000\"><ele>3.4</ele><time>2016-06-17T23:41:13Z</time><name>to</name></wpt>\n" +
"<wpt lat=\"37.778297000\" lon=\"-122.391174000\"><ele>3.4</ele><time>2016-06-17T23:41:18Z</time><name>via1</name></wpt>\n" +
"<wpt lat=\"37.778378000\" lon=\"-122.391117000\"><ele>3.4</ele><time>2016-06-17T23:41:23Z</time><name>nogo100 Test</name></wpt>\n" +
"</gpx>");
}
CoordinateReader coordinateReader = CoordinateReader.obtainValidReader(temporaryFolder.getRoot().getAbsolutePath(), false);
assertThat(coordinateReader, notNullValue());
// from, to, viaX are parsed into waypoints
assertThat(coordinateReader.waypoints, hasSize(3));
assertThat(coordinateReader.nogopoints, hasSize(1));
coordinateReader.readAllPoints();
assertThat(coordinateReader.allpoints, hasSize(4));
}
}

View file

@ -7,7 +7,6 @@
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -92,5 +91,15 @@
android:exported="true"
android:process=":brouter_service" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="btools.routing.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>

View file

@ -9,11 +9,10 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.StatFs;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.os.EnvironmentCompat;
@ -22,6 +21,7 @@ import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -43,30 +43,32 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
private static final int DIALOG_SELECTBASEDIR_ID = 11;
private static final int DIALOG_MAINACTION_ID = 12;
private static final int DIALOG_OLDDATAHINT_ID = 13;
private static final int DIALOG_SHOW_WP_HELP_ID = 14;
private static final int DIALOG_SHOW_WP_SCANRESULT_ID = 15;
private static final int DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID = 16;
private static final int DIALOG_SHOW_API23_HELP_ID = 17;
private final Set<Integer> dialogIds = new HashSet<>();
private BRouterView mBRouterView;
private PowerManager mPowerManager;
private WakeLock mWakeLock;
private String[] availableProfiles;
private String selectedProfile = null;
private List<File> availableBasedirs;
private String[] basedirOptions;
private int selectedBasedir;
private String[] availableWaypoints;
private String[] routingModes;
private boolean[] routingModesChecked;
private String message = null;
private String[] availableVias;
private Set<String> selectedVias;
private List<OsmNodeNamed> nogoList;
private String errorMessage;
private String title;
private int wpCount;
/**
* Called when the activity is first created.
*/
@Override
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get an instance of the PowerManager
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
// Create a bright wake lock
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName());
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass();
@ -77,7 +79,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
}
@Override
@SuppressWarnings("deprecation")
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(this);
@ -131,47 +132,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
}
});
return builder.create();
case DIALOG_SHOW_WP_HELP_ID:
builder
.setTitle("No Waypoint Database found")
.setMessage(
"The simple scan did not find any map-tool directory including a waypoint database. "
+ "Reason could be there is no map-tool installed (osmand, locus or oruxmaps), or at an "
+ "unusual path, or it contains no waypoints yet. That's o.k. if you want to use BRouter "
+ "in server-mode only - in that case you can still use the 'Server-Mode' button to "
+ "configure the profile mapping. But you will not be able to use nogo-points or do "
+ "long distance calculations. If you know the path to your map-tool, you can manually "
+ "configure it in 'storageconfig.txt'. Or I can do an extended scan searching "
+ "your sd-card for a valid waypoint database").setPositiveButton("Scan", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mBRouterView.startWpDatabaseScan();
}
}).setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_SHOW_API23_HELP_ID:
builder
.setTitle("Android >=6 limitations")
.setMessage(
"You are using the BRouter APP on Android >= 6, where classic mode is no longer supported. "
+ "Reason is that security policy does not permit any longer to read the waypoint databases of other apps. "
+ "That's o.k. if you want to use BRouter in server-mode only, where the apps actively send the waypoints "
+ "via a remote procedure call to BRouter (And Locus can also send nogo areas). "
+ "So the only functions you need to start the BRouter App are 1) to initially define the base directory "
+ "2) to download routing data files and 3) to configure the profile mapping via the 'Server-Mode' button. "
+ "You will eventually not be able to define nogo-areas (OsmAnd, Orux) or to do "
+ "very long distance calculations. If you want to get classic mode back, you can manually install "
+ "the APK of the BRouter App from the release page ( http://brouter.de/brouter/revisions.html ), which "
+ "is still built against Android API 10, and does not have these limitations. "
).setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID:
builder
.setTitle("Successfully prepared a timeout-free calculation")
@ -185,20 +145,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
}
});
return builder.create();
case DIALOG_SHOW_WP_SCANRESULT_ID:
builder
.setTitle("Waypoint Database ")
.setMessage("Found Waypoint-Database(s) for maptool-dir: " + maptoolDirCandidate
+ " Configure that?").setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mBRouterView.saveMaptoolDir(maptoolDirCandidate);
}
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
return builder.create();
case DIALOG_OLDDATAHINT_ID:
builder
.setTitle("Local setup needs reset")
@ -238,7 +184,7 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
builder.setTitle("Enter SDCARD base dir:");
builder.setMessage(message);
final EditText input = new EditText(this);
input.setText(defaultbasedir);
// input.setText(defaultbasedir);
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
@ -305,31 +251,46 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
});
return builder.create();
case DIALOG_SHOWRESULT_ID:
String leftLabel = wpCount < 0 ? (wpCount != -2 ? "Exit" : "Help") : (wpCount == 0 ? "Select from" : "Select to/via");
String rightLabel = wpCount < 2 ? (wpCount == -3 ? "Help" : "Server-Mode") : "Calc Route";
// -3: Repeated route calculation
// -2: Unused?
// -1: Route calculated
// other: Select waypoints for route calculation
builder.setTitle(title).setMessage(errorMessage);
builder.setTitle(title).setMessage(errorMessage).setPositiveButton(leftLabel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (wpCount == -2) {
showWaypointDatabaseHelp();
} else if (wpCount == -1 || wpCount == -3) {
finish();
} else {
mBRouterView.pickWaypoints();
}
}
}).setNegativeButton(rightLabel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (wpCount == -3) {
showRepeatTimeoutHelp();
} else if (wpCount < 2) {
// Neutral button
if (wpCount == 0) {
builder.setNeutralButton("Server-Mode", (dialog, which) -> {
mBRouterView.startConfigureService();
} else {
});
} else if (wpCount == -3) {
builder.setNeutralButton("Info", (dialog, which) -> {
showRepeatTimeoutHelp();
});
} else if (wpCount >= 2) {
builder.setNeutralButton("Calc Route", (dialog, which) -> {
mBRouterView.finishWaypointSelection();
mBRouterView.startProcessing(selectedProfile);
}
}
});
}
// Positive button
if (wpCount == -3 || wpCount == -1) {
builder.setPositiveButton("Share GPX", (dialog, which) -> {
mBRouterView.shareTrack();
finish();
});
} else if (wpCount >= 0) {
String selectLabel = wpCount == 0 ? "Select from" : "Select to/via";
builder.setPositiveButton(selectLabel, (dialog, which) -> {
mBRouterView.pickWaypoints();
});
}
// Negative button
builder.setNegativeButton("Exit", (dialog, which) -> {
finish();
});
return builder.create();
case DIALOG_MODECONFIGOVERVIEW_ID:
builder.setTitle("Success").setMessage(message).setPositiveButton("Exit", new DialogInterface.OnClickListener() {
@ -355,41 +316,18 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
private boolean[] getCheckedBooleanArray(int size) {
boolean[] checked = new boolean[size];
for (int i = 0; i < checked.length; i++) checked[i] = true;
Arrays.fill(checked, true);
return checked;
}
private String[] availableProfiles;
private String selectedProfile = null;
private List<File> 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;
private String maptoolDirCandidate;
@SuppressWarnings("deprecation")
public void selectProfile(String[] items) {
availableProfiles = items;
Arrays.sort(availableProfiles);
// show main dialog
showDialog(DIALOG_MAINACTION_ID);
}
@SuppressWarnings("deprecation")
public void startDownloadManager() {
if (!mBRouterView.hasUpToDateLookups()) {
showDialog(DIALOG_OLDDATAHINT_ID);
@ -398,19 +336,17 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
}
}
@SuppressWarnings("deprecation")
public void selectBasedir(ArrayList<File> items, String defaultBasedir, String message) {
this.defaultbasedir = defaultBasedir;
public void selectBasedir(ArrayList<File> items, String message) {
this.message = message;
availableBasedirs = items;
ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
ArrayList<Long> dirFreeSizes = new ArrayList<>();
for (File f : items) {
long size = 0L;
try {
StatFs stat = new StatFs(f.getAbsolutePath());
size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
} catch (Exception e) { /* ignore */ }
dirFreeSizes.add(Long.valueOf(size));
dirFreeSizes.add(size);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@ -431,7 +367,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
showDialog(DIALOG_SELECTBASEDIR_ID);
}
@SuppressWarnings("deprecation")
public void selectRoutingModes(String[] modes, boolean[] modesChecked, String message) {
routingModes = modes;
routingModesChecked = modesChecked;
@ -439,74 +374,45 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
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);
selectedVias = new HashSet<>(availableVias.length);
Collections.addAll(selectedVias, items);
showDialog(DIALOG_VIASELECT_ID);
}
@SuppressWarnings("deprecation")
public void selectWaypoint(String[] items) {
availableWaypoints = items;
showNewDialog(DIALOG_PICKWAYPOINT_ID);
}
@SuppressWarnings("deprecation")
public void showWaypointDatabaseHelp() {
if (mBRouterView.canAccessSdCard) {
showNewDialog(DIALOG_SHOW_WP_HELP_ID);
} else {
showNewDialog(DIALOG_SHOW_API23_HELP_ID);
}
}
@SuppressWarnings("deprecation")
public void showRepeatTimeoutHelp() {
showNewDialog(DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID);
}
@SuppressWarnings("deprecation")
public void showWpDatabaseScanSuccess(String bestGuess) {
maptoolDirCandidate = bestGuess;
showNewDialog(DIALOG_SHOW_WP_SCANRESULT_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))) {
if (dialogIds.contains(id)) {
removeDialog(id);
}
dialogIds.add(Integer.valueOf(id));
dialogIds.add(id);
showDialog(id);
}
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;
@ -514,50 +420,31 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
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();
}
@Override
protected void onPause() {
super.onPause();
/*
* When the activity is paused, we make sure to stop the router
*/
// Stop the simulation
// When the activity is paused, we make sure to stop the router
mBRouterView.stopRouting();
// and release our wake-lock
mWakeLock.release();
}
private String getStorageState(File f) {
return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED
}
public ArrayList<File> getStorageDirectories() {
ArrayList<File> list = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
list = new ArrayList<File>(Arrays.asList(getExternalMediaDirs()));
list = new ArrayList<>(Arrays.asList(getExternalMediaDirs()));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
list = new ArrayList<File>(Arrays.asList(getExternalFilesDirs(null)));
list = new ArrayList<>(Arrays.asList(getExternalFilesDirs(null)));
}
ArrayList<File> res = new ArrayList<File>();
ArrayList<File> res = new ArrayList<>();
if (list != null) {
for (File f : list) {
if (f != null) {
if (getStorageState(f).equals(Environment.MEDIA_MOUNTED))
if (EnvironmentCompat.getStorageState(f).equals(Environment.MEDIA_MOUNTED))
res.add(f);
}
}
}
if (checkExternalStorageWritable()) {
res.add(Environment.getExternalStorageDirectory());
@ -588,7 +475,7 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

View file

@ -1,7 +1,16 @@
package btools.routingapp;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Base64;
import android.util.Log;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -10,26 +19,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import java.util.ArrayList;
import android.Manifest;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Base64;
import androidx.core.content.ContextCompat;
import java.util.zip.GZIPOutputStream;
import btools.router.OsmNodeNamed;
@ -185,18 +177,7 @@ public class BRouterService extends Service {
private void readNogos(BRouterWorker worker, String baseDir) throws Exception {
// add nogos from waypoint database
int deviceLevel = android.os.Build.VERSION.SDK_INT;
int targetSdkVersion = getApplicationInfo().targetSdkVersion;
boolean canAccessSdCard = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) {
canAccessSdCard = false;
}
if (ContextCompat.checkSelfPermission(BRouterService.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
canAccessSdCard = false;
}
AppLogger.log("dev/target=" + deviceLevel + "/" + targetSdkVersion + " canAccessSdCard=" + canAccessSdCard);
CoordinateReader cor = CoordinateReader.obtainValidReader(baseDir, worker.segmentDir, canAccessSdCard, true);
CoordinateReader cor = CoordinateReader.obtainValidReader(baseDir, true);
worker.nogoList = new ArrayList<OsmNodeNamed>(cor.nogopoints);
worker.nogoPolygonsList = new ArrayList<OsmNodeNamed>();
}

View file

@ -2,19 +2,19 @@ package btools.routingapp;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@ -26,7 +26,6 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@ -47,10 +46,11 @@ import btools.router.RoutingHelper;
import btools.util.CheapRuler;
public class BRouterView extends View {
private final int memoryClass;
RoutingEngine cr;
private int imgw;
private int imgh;
private int centerLon;
private int centerLat;
private double scaleLon; // ilon -> pixel
@ -60,45 +60,35 @@ public class BRouterView extends View {
private List<OsmNodeNamed> nogoList;
private List<OsmNodeNamed> nogoVetoList;
private OsmTrack rawTrack;
private File retryBaseDir;
private File modesDir;
private File tracksDir;
private File segmentDir;
private File profileDir;
private String profilePath;
private String profileName;
private String sourceHint;
private boolean waitingForSelection = false;
private boolean waitingForMigration = false;
private String rawTrackPath;
private String oldMigrationPath;
private String trackOutfile;
private boolean needsViaSelection;
private boolean needsNogoSelection;
private boolean needsWaypointSelection;
private WpDatabaseScanner dataBaseScanner;
private long lastDataTime = System.currentTimeMillis();
private CoordinateReader cor;
private int[] imgPixels;
private int memoryClass;
public boolean canAccessSdCard;
public void stopRouting() {
if (cr != null) cr.terminate();
}
private long lastTs = System.currentTimeMillis();
private long startTime = 0L;
public BRouterView(Context context, int memoryClass) {
super(context);
this.memoryClass = memoryClass;
}
public void stopRouting() {
if (cr != null) cr.terminate();
}
public void init() {
try {
// get base dir from private file
@ -115,28 +105,26 @@ public class BRouterView extends View {
// don't ask twice
String version = "v" + getContext().getString(R.string.app_version);
File vFile = new File(brd, "profiles2/" + version);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q
&& vFile.exists()) {
if (vFile.exists()) {
startSetup(baseDir, false);
return;
}
String message = "(previous basedir " + baseDir + " has to migrate )";
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), guessBaseDir(), message);
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), message);
waitingForSelection = true;
waitingForMigration = true;
oldMigrationPath = brd.getAbsolutePath();
return;
} else {
startSetup(baseDir, false);
return;
}
return;
}
}
String message = baseDir == null ? "(no basedir configured previously)" : "(previous basedir " + baseDir
+ (bdValid ? " does not contain 'brouter' subfolder)" : " is not valid)");
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), guessBaseDir(), message);
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), message);
waitingForSelection = true;
} catch (Exception e) {
String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString();
@ -168,7 +156,7 @@ public class BRouterView extends View {
retryBaseDir = baseDir;
ActivityCompat.requestPermissions((BRouterActivity) getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
} else {
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), guessBaseDir(), "Cannot access " + baseDir.getAbsolutePath() + "; select another");
((BRouterActivity) getContext()).selectBasedir(((BRouterActivity) getContext()).getStorageDirectories(), "Cannot access " + baseDir.getAbsolutePath() + "; select another");
}
return;
}
@ -180,24 +168,7 @@ public class BRouterView extends View {
String basedir = baseDir.getAbsolutePath();
AppLogger.log("using basedir: " + basedir);
String version = "v" + getContext().getString(R.string.app_version);
// create missing directories
assertDirectoryExists("project directory", new File(basedir, "brouter"), null, null);
segmentDir = new File(basedir, "/brouter/segments4");
if (assertDirectoryExists("data directory", segmentDir, "segments4.zip", null)) {
ConfigMigration.tryMigrateStorageConfig(
new File(basedir + "/brouter/segments3/storageconfig.txt"),
new File(basedir + "/brouter/segments4/storageconfig.txt"));
}
profileDir = new File(basedir, "brouter/profiles2");
assertDirectoryExists("profile directory", profileDir, "profiles2.zip", version);
modesDir = new File(basedir, "/brouter/modes");
assertDirectoryExists("modes directory", modesDir, "modes.zip", version);
assertDirectoryExists("readmes directory", new File(basedir, "brouter/readmes"), "readmes.zip", version);
File inputDir = new File(basedir, "brouter/import");
assertDirectoryExists("input directory", inputDir, null, version);
populateBasedir(basedir);
// new init is done move old files
if (waitingForMigration) {
@ -207,23 +178,11 @@ public class BRouterView extends View {
waitingForMigration = false;
}
int deviceLevel = Build.VERSION.SDK_INT;
int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
canAccessSdCard = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) {
canAccessSdCard = false;
}
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
canAccessSdCard = false;
}
cor = CoordinateReader.obtainValidReader(basedir, segmentDir, canAccessSdCard);
cor = CoordinateReader.obtainValidReader(basedir);
wpList = cor.waypoints;
nogoList = cor.nogopoints;
nogoVetoList = new ArrayList<OsmNodeNamed>();
sourceHint = "(dev/trgt=" + deviceLevel + "/" + targetSdkVersion + " coordinate-source: " + cor.basedir + cor.rootdir + ")";
nogoVetoList = new ArrayList<>();
needsViaSelection = wpList.size() > 2;
needsNogoSelection = nogoList.size() > 0;
@ -232,34 +191,16 @@ public class BRouterView extends View {
if (cor.tracksdir != null) {
tracksDir = new File(cor.basedir, cor.tracksdir);
assertDirectoryExists("track directory", tracksDir, null, null);
// output redirect: look for a pointerfile in tracksdir
File tracksDirPointer = new File(tracksDir, "brouter.redirect");
if (tracksDirPointer.isFile()) {
String tracksDirStr = readSingleLineFile(tracksDirPointer);
if (tracksDirStr == null)
throw new IllegalArgumentException("redirect pointer file is empty: " + tracksDirPointer);
tracksDir = new File(tracksDirStr);
if (!(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 = null;
}
}
}
if (tracksDir == null) {
tracksDir = new File(basedir, "brouter"); // fallback
}
String[] fileNames = profileDir.list();
ArrayList<String> profiles = new ArrayList<String>();
ArrayList<String> profiles = new ArrayList<>();
boolean lookupsFound = false;
if (fileNames != null) {
for (String fileName : fileNames) {
if (fileName.endsWith(".brf")) {
profiles.add(fileName.substring(0, fileName.length() - 4));
@ -267,6 +208,7 @@ public class BRouterView extends View {
if (fileName.equals("lookups.dat"))
lookupsFound = true;
}
}
// add a "last timeout" dummy profile
File lastTimeoutFile = new File(modesDir + "/timeoutdata.txt");
@ -304,9 +246,31 @@ public class BRouterView extends View {
waitingForSelection = true;
}
private void populateBasedir(String basedir) {
String version = "v" + getContext().getString(R.string.app_version);
// create missing directories
assertDirectoryExists("project directory", new File(basedir, "brouter"), null, null);
segmentDir = new File(basedir, "/brouter/segments4");
if (assertDirectoryExists("data directory", segmentDir, "segments4.zip", null)) {
ConfigMigration.tryMigrateStorageConfig(
new File(basedir + "/brouter/segments3/storageconfig.txt"),
new File(basedir + "/brouter/segments4/storageconfig.txt"));
}
profileDir = new File(basedir, "brouter/profiles2");
assertDirectoryExists("profile directory", profileDir, "profiles2.zip", version);
modesDir = new File(basedir, "/brouter/modes");
assertDirectoryExists("modes directory", modesDir, "modes.zip", version);
assertDirectoryExists("readmes directory", new File(basedir, "brouter/readmes"), "readmes.zip", version);
File inputDir = new File(basedir, "brouter/import");
assertDirectoryExists("input directory", inputDir, null, version);
}
private void moveFolders(String oldMigrationPath, String basedir) {
File oldDir = new File(oldMigrationPath);
File[] oldFiles = oldDir.listFiles();
if (oldFiles != null) {
for (File f : oldFiles) {
if (f.isDirectory()) {
int index = f.getAbsolutePath().lastIndexOf("/");
@ -320,22 +284,21 @@ public class BRouterView extends View {
}
}
}
private void moveFile(String inputPath, String inputFile, String outputPath) {
private void copyFile(String inputPath, String inputFile, String outputPath) {
InputStream in;
OutputStream out;
InputStream in = null;
OutputStream out = null;
try {
//create output directory if it doesn't exist
File dir = new File(outputPath);
if (!dir.exists()) {
dir.mkdirs();
}
in = new FileInputStream(inputPath + "/" + inputFile);
out = new FileOutputStream(outputPath + "/" + inputFile);
in = new FileInputStream(new File(inputPath, inputFile));
out = new FileOutputStream(new File(outputPath, inputFile));
byte[] buffer = new byte[1024];
int read;
@ -343,23 +306,22 @@ public class BRouterView extends View {
out.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file
out.flush();
out.close();
out = null;
// delete the original file
new File(inputPath + "/" + inputFile).delete();
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
} catch (FileNotFoundException fileNotFoundException) {
Log.e("tag", fileNotFoundException.getMessage());
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
private void moveFile(String inputPath, String inputFile, String outputPath) {
copyFile(inputPath, inputFile, outputPath);
// delete the original file
new File(inputPath, inputFile).delete();
}
public boolean hasUpToDateLookups() {
@ -374,7 +336,7 @@ public class BRouterView extends View {
}
public void updateViaList(Set<String> selectedVias) {
ArrayList<OsmNodeNamed> filtered = new ArrayList<OsmNodeNamed>(wpList.size());
ArrayList<OsmNodeNamed> filtered = new ArrayList<>(wpList.size());
for (OsmNodeNamed n : wpList) {
String name = n.name;
if ("from".equals(name) || "to".equals(name) || selectedVias.contains(name))
@ -399,7 +361,7 @@ public class BRouterView extends View {
try {
cor.readAllPoints();
} catch (Exception e) {
msg = "Error reading waypoints: " + e.toString();
msg = "Error reading waypoints: " + e;
}
int size = cor.allpoints.size();
@ -434,24 +396,13 @@ public class BRouterView extends View {
}
}
public void startWpDatabaseScan() {
dataBaseScanner = new WpDatabaseScanner();
dataBaseScanner.start();
invalidate();
}
public void saveMaptoolDir(String dir) {
ConfigMigration.saveAdditionalMaptoolDir(segmentDir, dir);
((BRouterActivity) getContext()).showResultMessage("Success", "please restart to use new config", -1);
}
public void finishWaypointSelection() {
needsWaypointSelection = false;
}
private List<OsmNodeNamed> readWpList(BufferedReader br, boolean isNogo) throws Exception {
int cnt = Integer.parseInt(br.readLine());
List<OsmNodeNamed> res = new ArrayList<OsmNodeNamed>(cnt);
List<OsmNodeNamed> res = new ArrayList<>(cnt);
for (int i = 0; i < cnt; i++) {
OsmNodeNamed wp = OsmNodeNamed.decodeNogo(br.readLine());
wp.isNogo = isNogo;
@ -480,7 +431,7 @@ public class BRouterView extends View {
rawTrackPath = modesDir + "/remote_rawtrack.dat";
}
profilePath = profileDir + "/" + profile + ".brf";
String profilePath = profileDir + "/" + profile + ".brf";
profileName = profile;
if (needsViaSelection) {
@ -499,15 +450,15 @@ public class BRouterView extends View {
}
if (needsWaypointSelection) {
String msg;
StringBuilder msg;
if (wpList.size() == 0) {
msg = "Expecting waypoint selection\n" + sourceHint;
msg = new StringBuilder("Expecting waypoint selection\n" + "(coordinate-source: " + cor.basedir + cor.rootdir + ")");
} else {
msg = "current waypoint selection:\n";
msg = new StringBuilder("current waypoint selection:\n");
for (int i = 0; i < wpList.size(); i++)
msg += (i > 0 ? "->" : "") + wpList.get(i).name;
msg.append(i > 0 ? "->" : "").append(wpList.get(i).name);
}
((BRouterActivity) getContext()).showResultMessage("Select Action", msg, wpList.size());
((BRouterActivity) getContext()).showResultMessage("Select Action", msg.toString(), wpList.size());
return;
}
@ -587,7 +538,7 @@ public class BRouterView extends View {
File vtag = new File(path, versionTag);
try {
exists = !vtag.createNewFile();
} catch (IOException io) {
} catch (IOException ignored) {
} // well..
}
@ -608,7 +559,7 @@ public class BRouterView extends View {
}
String name = ze.getName();
File outfile = new File(path, name);
if (!outfile.exists()) {
if (!outfile.exists() && outfile.getParentFile() != null) {
outfile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(outfile);
@ -656,7 +607,7 @@ public class BRouterView extends View {
int ir = (int) (n.radius * scaleMeter2Pixel);
if (ir > minradius) {
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle((float) x, (float) y, (float) ir, paint);
}
@ -703,9 +654,6 @@ public class BRouterView extends View {
lastDataTime += 4000; // give time for the toast before exiting
}
private long lastTs = System.currentTimeMillis();
private long startTime = 0L;
@Override
protected void onDraw(Canvas canvas) {
try {
@ -717,58 +665,14 @@ public class BRouterView extends View {
cr = null;
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
} catch (InterruptedException ignored) {
}
((BRouterActivity) getContext()).showErrorMessage(t.toString());
waitingForSelection = true;
}
}
private void showDatabaseScanning(Canvas canvas) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
Paint paint1 = new Paint();
paint1.setColor(Color.WHITE);
paint1.setTextSize(20);
Paint paint2 = new Paint();
paint2.setColor(Color.WHITE);
paint2.setTextSize(10);
String currentDir = dataBaseScanner.getCurrentDir();
String bestGuess = dataBaseScanner.getBestGuess();
if (currentDir == null) // scan finished
{
if (bestGuess.length() == 0) {
((BRouterActivity) getContext()).showErrorMessage("scan did not find any possible waypoint database");
} else {
((BRouterActivity) getContext()).showWpDatabaseScanSuccess(bestGuess);
}
cr = null;
dataBaseScanner = null;
waitingForSelection = true;
return;
}
canvas.drawText("Scanning:", 10, 30, paint1);
canvas.drawText(currentDir, 0, 60, paint2);
canvas.drawText("Best Guess:", 10, 90, paint1);
canvas.drawText(bestGuess, 0, 120, paint2);
canvas.drawText("Last Error:", 10, 150, paint1);
canvas.drawText(dataBaseScanner.getLastError(), 0, 180, paint2);
invalidate();
}
private void _onDraw(Canvas canvas) {
if (dataBaseScanner != null) {
showDatabaseScanning(canvas);
return;
}
if (waitingForSelection)
return;
@ -780,7 +684,7 @@ public class BRouterView extends View {
try {
Thread.sleep(sleeptime);
} catch (InterruptedException ie) {
} catch (InterruptedException ignored) {
}
lastTs = System.currentTimeMillis();
@ -788,9 +692,6 @@ public class BRouterView extends View {
if (cr != null) {
if (cr.getErrorMessage() != null) {
((BRouterActivity) getContext()).showErrorMessage(cr.getErrorMessage());
cr = null;
waitingForSelection = true;
return;
} else {
String memstat = memoryClass + "mb pathPeak " + ((cr.getPathPeak() + 500) / 1000) + "k";
String result = "version = BRouter-" + getContext().getString(R.string.app_version) + "\n" + "mem = " + memstat + "\ndistance = " + cr.getDistance() / 1000. + " km\n" + "filtered ascend = " + cr.getAscend()
@ -808,10 +709,11 @@ public class BRouterView extends View {
title += " / " + cr.getAlternativeIndex() + ". Alternative";
((BRouterActivity) getContext()).showResultMessage(title, result, rawTrackPath == null ? -1 : -3);
trackOutfile = cr.getOutfile();
}
cr = null;
waitingForSelection = true;
return;
}
} else if (System.currentTimeMillis() > lastDataTime) {
System.exit(0);
}
@ -824,17 +726,18 @@ public class BRouterView extends View {
paintPosition(openSet[si], openSet[si + 1], 0xffffff, 1);
}
// paint nogos on top (red)
int minradius = 4;
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
OsmNodeNamed n = nogoList.get(ngi);
int color = 0xff0000;
paintPosition(n.ilon, n.ilat, color, 4);
paintPosition(n.ilon, n.ilat, color, minradius);
}
// paint start/end/vias on top (yellow/green/blue)
for (int wpi = 0; wpi < wpList.size(); wpi++) {
OsmNodeNamed n = wpList.get(wpi);
int color = wpi == 0 ? 0xffff00 : wpi < wpList.size() - 1 ? 0xff : 0xff00;
paintPosition(n.ilon, n.ilat, color, 4);
paintPosition(n.ilon, n.ilat, color, minradius);
}
canvas.drawBitmap(imgPixels, 0, imgw, (float) 0., (float) 0., imgw, imgh, false, null);
@ -843,10 +746,10 @@ public class BRouterView extends View {
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
OsmNodeNamed n = nogoList.get(ngi);
if (n instanceof OsmNogoPolygon) {
paintPolygon(canvas, (OsmNogoPolygon) n, 4);
paintPolygon(canvas, (OsmNogoPolygon) n, minradius);
} else {
int color = 0xff0000;
paintCircle(canvas, n, color, 4);
int color = Color.RED;
paintCircle(canvas, n, color, minradius);
}
}
@ -865,42 +768,6 @@ public class BRouterView extends View {
invalidate();
}
private String guessBaseDir() {
File basedir = Environment.getExternalStorageDirectory();
try {
File bd2 = new File(basedir, "external_sd");
ArrayList<String> basedirGuesses = new ArrayList<String>();
basedirGuesses.add(basedir.getAbsolutePath());
if (bd2.exists()) {
basedir = bd2;
basedirGuesses.add(basedir.getAbsolutePath());
}
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
for (String bdg : basedirGuesses) {
rl.add(new CoordinateReaderOsmAnd(bdg));
rl.add(new CoordinateReaderLocus(bdg));
rl.add(new CoordinateReaderOrux(bdg));
}
long tmax = 0;
CoordinateReader cor = null;
for (CoordinateReader r : rl) {
long t = r.getTimeStamp();
if (t > tmax) {
tmax = t;
cor = r;
}
}
if (cor != null) {
return cor.basedir;
}
} catch (Exception e) {
System.out.println("guessBaseDir:" + e);
}
return basedir.getAbsolutePath();
}
private void writeRawTrackToMode(String mode) {
writeRawTrackToPath(modesDir + "/" + mode + "_rawtrack.dat");
}
@ -909,7 +776,7 @@ public class BRouterView extends View {
if (rawTrack != null) {
try {
rawTrack.writeBinary(rawTrackPath);
} catch (Exception e) {
} catch (Exception ignored) {
}
} else {
new File(rawTrackPath).delete();
@ -928,7 +795,7 @@ public class BRouterView extends View {
public void configureService(String[] routingModes, boolean[] checkedModes) {
// read in current config
TreeMap<String, ServiceModeConfig> map = new TreeMap<String, ServiceModeConfig>();
TreeMap<String, ServiceModeConfig> map = new TreeMap<>();
BufferedReader br = null;
String modesFile = modesDir + "/serviceconfig.dat";
try {
@ -940,12 +807,12 @@ public class BRouterView extends View {
ServiceModeConfig smc = new ServiceModeConfig(line);
map.put(smc.mode, smc);
}
} catch (Exception e) {
} catch (Exception ignored) {
} finally {
if (br != null)
try {
br.close();
} catch (Exception ee) {
} catch (Exception ignored) {
}
}
@ -971,27 +838,29 @@ public class BRouterView extends View {
for (ServiceModeConfig smc : map.values()) {
bw.write(smc.toLine());
bw.write('\n');
msg.append(smc.toString()).append('\n');
msg.append(smc).append('\n');
}
} catch (Exception e) {
} catch (Exception ignored) {
} finally {
if (bw != null)
try {
bw.close();
} catch (Exception ee) {
} catch (Exception ignored) {
}
}
((BRouterActivity) getContext()).showModeConfigOverview(msg.toString());
}
private String readSingleLineFile(File f) {
try (FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr)) {
return br.readLine();
} catch (Exception e) {
return null;
public void shareTrack() {
File track = new File(trackOutfile);
// Copy file to cache to ensure FileProvider allows sharing the file
File cacheDir = getContext().getCacheDir();
copyFile(track.getParent(), track.getName(), cacheDir.getAbsolutePath());
Intent intent = new Intent();
intent.setDataAndType(FileProvider.getUriForFile(getContext(), "btools.routing.fileprovider", new File(cacheDir, track.getName())),
"application/gpx+xml");
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
getContext().startActivity(intent);
}
}
}

View file

@ -1,8 +1,18 @@
package btools.routingapp;
import android.graphics.Point;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -10,47 +20,182 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.os.Environment;
import btools.router.OsmNodeNamed;
import btools.router.RoutingHelper;
import btools.router.OsmNogoPolygon;
/**
* Read coordinates from a gpx-file
*/
public abstract class CoordinateReader {
public class CoordinateReader {
protected static String[] posnames
= new String[]{"from", "via1", "via2", "via3", "via4", "via5", "via6", "via7", "via8", "via9", "to"};
private final String internalDir;
public List<OsmNodeNamed> waypoints;
public List<OsmNodeNamed> nogopoints;
public String basedir;
public String rootdir;
public String tracksdir;
private boolean nogosOnly;
private Map<String, Map<String, OsmNodeNamed>> allpointsMap;
public List<OsmNodeNamed> allpoints;
private boolean nogosOnly;
private Map<String, Map<String, OsmNodeNamed>> allpointsMap;
private HashMap<String, OsmNodeNamed> pointmap;
protected static String[] posnames
= new String[]{"from", "via1", "via2", "via3", "via4", "via5", "via6", "via7", "via8", "via9", "to"};
public CoordinateReader(String basedir) {
this.basedir = basedir;
internalDir = basedir + "/brouter/import";
tracksdir = "/brouter/import/tracks";
rootdir = "/brouter/import";
}
public abstract long getTimeStamp() throws Exception;
public static CoordinateReader obtainValidReader(String basedir) throws IOException {
return obtainValidReader(basedir, false);
}
public abstract int getTurnInstructionMode();
public static CoordinateReader obtainValidReader(String basedir, boolean nogosOnly) throws IOException {
CoordinateReader cor = new CoordinateReader(basedir);
cor.nogosOnly = nogosOnly;
cor.readFromTo();
return cor;
}
public int getTurnInstructionMode() {
return 4; // comment style
}
/*
* read the from and to position from a gpx-file
* (with hardcoded name for now)
*/
public void readPointmap() throws IOException {
if (!_readPointmap(internalDir + "/favourites_bak.gpx")) {
_readPointmap(internalDir + "/favourites.gpx");
}
_readNogoLines(basedir + tracksdir);
}
private boolean _readPointmap(String filename) throws IOException {
BufferedReader br;
try {
br = new BufferedReader(
new InputStreamReader(
new FileInputStream(filename)));
} catch (FileNotFoundException e) {
// ignore until it's reading error
return false;
}
OsmNodeNamed n = null;
for (; ; ) {
String line = br.readLine();
if (line == null) break;
int idx0 = line.indexOf(" lat=\"");
int idx10 = line.indexOf("<name>");
if (idx0 >= 0) {
n = new OsmNodeNamed();
idx0 += 6;
int idx1 = line.indexOf('"', idx0);
n.ilat = (int) ((Double.parseDouble(line.substring(idx0, idx1)) + 90.) * 1000000. + 0.5);
int idx2 = line.indexOf(" lon=\"");
if (idx2 < 0) continue;
idx2 += 6;
int idx3 = line.indexOf('"', idx2);
n.ilon = (int) ((Double.parseDouble(line.substring(idx2, idx3)) + 180.) * 1000000. + 0.5);
if (idx3 < 0) continue;
}
if (n != null && idx10 >= 0) {
idx10 += 6;
int idx11 = line.indexOf("</name>", idx10);
if (idx11 >= 0) {
n.name = line.substring(idx10, idx11).trim();
checkAddPoint("(one-for-all)", n);
}
}
}
br.close();
return true;
}
private void _readNogoLines(String dirname) {
File dir = new File(dirname);
if (dir.exists() && dir.isDirectory()) {
for (final File file : dir.listFiles()) {
final String name = file.getName();
if (name.startsWith("nogo") && name.endsWith(".gpx")) {
try {
_readNogoLine(file);
} catch (Exception ignored) {
}
}
}
}
}
private void _readNogoLine(File file) throws Exception {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new FileReader(file));
List<Point> tmpPts = new ArrayList<>();
int eventType = xpp.getEventType();
int numSeg = 0;
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG: {
if (xpp.getName().equals("trkpt") || xpp.getName().equals("rtept")) {
final String lon = xpp.getAttributeValue(null, "lon");
final String lat = xpp.getAttributeValue(null, "lat");
if (lon != null && lat != null) {
tmpPts.add(new Point(
(int) ((Double.parseDouble(lon) + 180.) * 1000000. + 0.5),
(int) ((Double.parseDouble(lat) + 90.) * 1000000. + 0.5)));
}
}
break;
}
case XmlPullParser.END_TAG: {
if (xpp.getName().equals("trkseg") || xpp.getName().equals("rte")) { // rte has no segment
OsmNogoPolygon nogo;
if (tmpPts.size() > 0) {
if (tmpPts.get(0).x == tmpPts.get(tmpPts.size() - 1).x &&
tmpPts.get(0).y == tmpPts.get(tmpPts.size() - 1).y) {
nogo = new OsmNogoPolygon(true);
} else {
nogo = new OsmNogoPolygon(false);
}
for (Point p : tmpPts) {
nogo.addVertex(p.x, p.y);
}
nogo.calcBoundingCircle();
final String name = file.getName();
nogo.name = name.substring(0, name.length() - 4);
if (numSeg > 0) {
nogo.name += Integer.toString(numSeg + 1);
}
numSeg++;
checkAddPoint("(one-for-all)", nogo);
}
tmpPts.clear();
}
break;
}
}
eventType = xpp.next();
}
}
public void readAllPoints() throws Exception {
allpointsMap = new TreeMap<String, Map<String, OsmNodeNamed>>();
allpointsMap = new TreeMap<>();
readFromTo();
allpoints = new ArrayList<OsmNodeNamed>();
Set<String> names = new HashSet<String>();
allpoints = new ArrayList<>();
Set<String> names = new HashSet<>();
for (String category : allpointsMap.keySet()) {
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
if (cat.size() < 101) {
if (cat != null && cat.size() < 101) {
for (OsmNodeNamed wp : cat.values()) {
if (names.add(wp.name)) {
allpoints.add(wp);
@ -67,14 +212,13 @@ public abstract class CoordinateReader {
/*
* read the from, to and via-positions from a gpx-file
*/
public void readFromTo() throws Exception {
pointmap = new HashMap<String, OsmNodeNamed>();
waypoints = new ArrayList<OsmNodeNamed>();
nogopoints = new ArrayList<OsmNodeNamed>();
public void readFromTo() throws IOException {
pointmap = new HashMap<>();
waypoints = new ArrayList<>();
nogopoints = new ArrayList<>();
readPointmap();
boolean fromToMissing = false;
for (int i = 0; i < posnames.length; i++) {
String name = posnames[i];
for (String name : posnames) {
OsmNodeNamed n = pointmap.get(name);
if (n != null) {
waypoints.add(n);
@ -91,7 +235,7 @@ public abstract class CoordinateReader {
if (category == null) category = "";
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
if (cat == null) {
cat = new TreeMap<String, OsmNodeNamed>();
cat = new TreeMap<>();
allpointsMap.put(category, cat);
}
if (cat.size() < 101) {
@ -101,8 +245,8 @@ public abstract class CoordinateReader {
}
boolean isKnown = false;
for (int i = 0; i < posnames.length; i++) {
if (posnames[i].equals(n.name)) {
for (String posname : posnames) {
if (posname.equals(n.name)) {
isKnown = true;
break;
}
@ -121,74 +265,4 @@ public abstract class CoordinateReader {
}
}
protected abstract void readPointmap() throws Exception;
public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard) throws Exception {
return obtainValidReader(basedir, segmentDir, canAccessSdCard, false);
}
public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard, boolean nogosOnly) throws Exception {
CoordinateReader cor = null;
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();
if (canAccessSdCard) {
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 explicit directory
File additional = RoutingHelper.getAdditionalMaptoolDir(segmentDir);
if (additional != null) {
String base3 = additional.getAbsolutePath();
AppLogger.log("adding maptool-base from storage-config: " + 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 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 > tmax) {
tmax = t;
cor = r;
}
}
}
if (cor == null) {
cor = new CoordinateReaderInternal(basedir);
}
cor.nogosOnly = nogosOnly;
cor.readFromTo();
return cor;
}
}

View file

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

View file

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

View file

@ -1,63 +0,0 @@
package btools.routingapp;
import java.io.File;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import btools.router.OsmNodeNamed;
/**
* Read coordinates from a gpx-file
*/
public class CoordinateReaderOrux extends CoordinateReader {
public CoordinateReaderOrux(String basedir) {
super(basedir);
tracksdir = "/oruxmaps/tracklogs";
rootdir = "/oruxmaps";
}
@Override
public long getTimeStamp() throws Exception {
File f = new File(basedir + "/oruxmaps/tracklogs/oruxmapstracks.db");
long t1 = f.lastModified();
// Android 10 delivers file size but can't read it
boolean canRead = f.canRead();
return canRead ? t1 : 0L;
}
@Override
public int getTurnInstructionMode() {
return 0; // none
}
/*
* read the from and to position from a ggx-file
* (with hardcoded name for now)
*/
@Override
public void readPointmap() throws Exception {
_readPointmap(basedir + "/oruxmaps/tracklogs/oruxmapstracks.db");
}
private void _readPointmap(String filename) throws Exception {
SQLiteDatabase myDataBase = null;
try {
myDataBase = SQLiteDatabase.openDatabase(filename, null, SQLiteDatabase.OPEN_READONLY);
} catch (Exception e) {
// not open, do not produce an error
return;
}
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) ((c.getDouble(1) + 180.) * 1000000. + 0.5);
n.ilat = (int) ((c.getDouble(2) + 90.) * 1000000. + 0.5);
String category = c.getString(3);
checkAddPoint(category, n);
}
c.close();
myDataBase.close();
}
}

View file

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

View file

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

View file

@ -0,0 +1,5 @@
<paths>
<cache-path
name="cache"
path="." />
</paths>