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:
commit
9d37e2c648
14 changed files with 492 additions and 1181 deletions
|
@ -63,6 +63,7 @@ public class RoutingEngine extends Thread
|
||||||
private Object[] extract;
|
private Object[] extract;
|
||||||
|
|
||||||
private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" );
|
private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" );
|
||||||
|
private String outfile;
|
||||||
|
|
||||||
public RoutingEngine( String outfileBase, String logfileBase, File segmentDir,
|
public RoutingEngine( String outfileBase, String logfileBase, File segmentDir,
|
||||||
List<OsmNodeNamed> waypoints, RoutingContext rc )
|
List<OsmNodeNamed> waypoints, RoutingContext rc )
|
||||||
|
@ -185,6 +186,7 @@ public class RoutingEngine extends Thread
|
||||||
track.writeGpx( filename );
|
track.writeGpx( filename );
|
||||||
foundTrack = track;
|
foundTrack = track;
|
||||||
alternativeIndex = i;
|
alternativeIndex = i;
|
||||||
|
outfile = filename;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1369,4 +1371,7 @@ public class RoutingEngine extends Thread
|
||||||
return terminated;
|
return terminated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOutfile() {
|
||||||
|
return outfile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ android {
|
||||||
setProperty("archivesBaseName", "BRouterApp." + defaultConfig.versionName)
|
setProperty("archivesBaseName", "BRouterApp." + defaultConfig.versionName)
|
||||||
|
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
|
targetSdkVersion 30
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
@ -73,21 +74,6 @@ android {
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
flavorDimensions "api"
|
|
||||||
productFlavors {
|
|
||||||
api19 {
|
|
||||||
dimension "api"
|
|
||||||
|
|
||||||
targetSdkVersion 19
|
|
||||||
}
|
|
||||||
api30 {
|
|
||||||
dimension "api"
|
|
||||||
|
|
||||||
targetSdkVersion 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationVariants.all {
|
applicationVariants.all {
|
||||||
variant ->
|
variant ->
|
||||||
{
|
{
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
tools:ignore="ScopedStorage" />
|
tools:ignore="ScopedStorage" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
@ -92,5 +91,15 @@
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:process=":brouter_service" />
|
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>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -9,11 +9,10 @@ import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.PowerManager;
|
|
||||||
import android.os.PowerManager.WakeLock;
|
|
||||||
import android.os.StatFs;
|
import android.os.StatFs;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.os.EnvironmentCompat;
|
import androidx.core.os.EnvironmentCompat;
|
||||||
|
@ -22,6 +21,7 @@ import java.io.File;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
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_SELECTBASEDIR_ID = 11;
|
||||||
private static final int DIALOG_MAINACTION_ID = 12;
|
private static final int DIALOG_MAINACTION_ID = 12;
|
||||||
private static final int DIALOG_OLDDATAHINT_ID = 13;
|
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_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 BRouterView mBRouterView;
|
||||||
private PowerManager mPowerManager;
|
private String[] availableProfiles;
|
||||||
private WakeLock mWakeLock;
|
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.
|
* Called when the activity is first created.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(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);
|
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||||||
int memoryClass = am.getMemoryClass();
|
int memoryClass = am.getMemoryClass();
|
||||||
|
|
||||||
|
@ -77,7 +79,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
protected Dialog onCreateDialog(int id) {
|
protected Dialog onCreateDialog(int id) {
|
||||||
AlertDialog.Builder builder;
|
AlertDialog.Builder builder;
|
||||||
builder = new AlertDialog.Builder(this);
|
builder = new AlertDialog.Builder(this);
|
||||||
|
@ -120,57 +121,16 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
"*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
|
"*** Attention: ***\n\n" + "The Download Manager is used to download routing-data "
|
||||||
+ "files which can be up to 170MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! "
|
+ "files which can be up to 170MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! "
|
||||||
+ "Download speed is restricted to 16 MBit/s.").setPositiveButton("I know", new DialogInterface.OnClickListener() {
|
+ "Download speed is restricted to 16 MBit/s.").setPositiveButton("I know", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class);
|
Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
showNewDialog(DIALOG_MAINACTION_ID);
|
showNewDialog(DIALOG_MAINACTION_ID);
|
||||||
}
|
}
|
||||||
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
|
||||||
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();
|
return builder.create();
|
||||||
case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID:
|
case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID:
|
||||||
builder
|
builder
|
||||||
|
@ -180,24 +140,10 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
+ "when started from your map-tool. If you repeat the same request from your "
|
+ "when started from your map-tool. If you repeat the same request from your "
|
||||||
+ "maptool, with the exact same destination point and a close-by starting point, "
|
+ "maptool, with the exact same destination point and a close-by starting point, "
|
||||||
+ "this request is guaranteed not to time out.").setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
+ "this request is guaranteed not to time out.").setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
|
||||||
case DIALOG_SHOW_WP_SCANRESULT_ID:
|
|
||||||
builder
|
|
||||||
.setTitle("Waypoint Database ")
|
|
||||||
.setMessage("Found Waypoint-Database(s) for maptool-dir: " + maptoolDirCandidate
|
|
||||||
+ " Configure that?").setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
mBRouterView.saveMaptoolDir(maptoolDirCandidate);
|
|
||||||
}
|
|
||||||
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return builder.create();
|
return builder.create();
|
||||||
case DIALOG_OLDDATAHINT_ID:
|
case DIALOG_OLDDATAHINT_ID:
|
||||||
builder
|
builder
|
||||||
|
@ -238,7 +184,7 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
builder.setTitle("Enter SDCARD base dir:");
|
builder.setTitle("Enter SDCARD base dir:");
|
||||||
builder.setMessage(message);
|
builder.setMessage(message);
|
||||||
final EditText input = new EditText(this);
|
final EditText input = new EditText(this);
|
||||||
input.setText(defaultbasedir);
|
// input.setText(defaultbasedir);
|
||||||
builder.setView(input);
|
builder.setView(input);
|
||||||
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
@ -305,31 +251,46 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
case DIALOG_SHOWRESULT_ID:
|
case DIALOG_SHOWRESULT_ID:
|
||||||
String leftLabel = wpCount < 0 ? (wpCount != -2 ? "Exit" : "Help") : (wpCount == 0 ? "Select from" : "Select to/via");
|
// -3: Repeated route calculation
|
||||||
String rightLabel = wpCount < 2 ? (wpCount == -3 ? "Help" : "Server-Mode") : "Calc Route";
|
// -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() {
|
// Neutral button
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
if (wpCount == 0) {
|
||||||
if (wpCount == -2) {
|
builder.setNeutralButton("Server-Mode", (dialog, which) -> {
|
||||||
showWaypointDatabaseHelp();
|
mBRouterView.startConfigureService();
|
||||||
} else if (wpCount == -1 || wpCount == -3) {
|
});
|
||||||
finish();
|
} else if (wpCount == -3) {
|
||||||
} else {
|
builder.setNeutralButton("Info", (dialog, which) -> {
|
||||||
mBRouterView.pickWaypoints();
|
showRepeatTimeoutHelp();
|
||||||
}
|
});
|
||||||
}
|
} else if (wpCount >= 2) {
|
||||||
}).setNegativeButton(rightLabel, new DialogInterface.OnClickListener() {
|
builder.setNeutralButton("Calc Route", (dialog, which) -> {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
mBRouterView.finishWaypointSelection();
|
||||||
if (wpCount == -3) {
|
mBRouterView.startProcessing(selectedProfile);
|
||||||
showRepeatTimeoutHelp();
|
});
|
||||||
} else if (wpCount < 2) {
|
}
|
||||||
mBRouterView.startConfigureService();
|
|
||||||
} else {
|
// Positive button
|
||||||
mBRouterView.finishWaypointSelection();
|
if (wpCount == -3 || wpCount == -1) {
|
||||||
mBRouterView.startProcessing(selectedProfile);
|
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();
|
return builder.create();
|
||||||
case DIALOG_MODECONFIGOVERVIEW_ID:
|
case DIALOG_MODECONFIGOVERVIEW_ID:
|
||||||
builder.setTitle("Success").setMessage(message).setPositiveButton("Exit", new DialogInterface.OnClickListener() {
|
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) {
|
private boolean[] getCheckedBooleanArray(int size) {
|
||||||
boolean[] checked = new boolean[size];
|
boolean[] checked = new boolean[size];
|
||||||
for (int i = 0; i < checked.length; i++) checked[i] = true;
|
Arrays.fill(checked, true);
|
||||||
return checked;
|
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) {
|
public void selectProfile(String[] items) {
|
||||||
availableProfiles = items;
|
availableProfiles = items;
|
||||||
|
Arrays.sort(availableProfiles);
|
||||||
|
|
||||||
// show main dialog
|
// show main dialog
|
||||||
showDialog(DIALOG_MAINACTION_ID);
|
showDialog(DIALOG_MAINACTION_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void startDownloadManager() {
|
public void startDownloadManager() {
|
||||||
if (!mBRouterView.hasUpToDateLookups()) {
|
if (!mBRouterView.hasUpToDateLookups()) {
|
||||||
showDialog(DIALOG_OLDDATAHINT_ID);
|
showDialog(DIALOG_OLDDATAHINT_ID);
|
||||||
|
@ -398,19 +336,17 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
public void selectBasedir(ArrayList<File> items, String message) {
|
||||||
public void selectBasedir(ArrayList<File> items, String defaultBasedir, String message) {
|
|
||||||
this.defaultbasedir = defaultBasedir;
|
|
||||||
this.message = message;
|
this.message = message;
|
||||||
availableBasedirs = items;
|
availableBasedirs = items;
|
||||||
ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
|
ArrayList<Long> dirFreeSizes = new ArrayList<>();
|
||||||
for (File f : items) {
|
for (File f : items) {
|
||||||
long size = 0L;
|
long size = 0L;
|
||||||
try {
|
try {
|
||||||
StatFs stat = new StatFs(f.getAbsolutePath());
|
StatFs stat = new StatFs(f.getAbsolutePath());
|
||||||
size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
|
size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
|
||||||
} catch (Exception e) { /* ignore */ }
|
} catch (Exception e) { /* ignore */ }
|
||||||
dirFreeSizes.add(Long.valueOf(size));
|
dirFreeSizes.add(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
@ -431,7 +367,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
showDialog(DIALOG_SELECTBASEDIR_ID);
|
showDialog(DIALOG_SELECTBASEDIR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void selectRoutingModes(String[] modes, boolean[] modesChecked, String message) {
|
public void selectRoutingModes(String[] modes, boolean[] modesChecked, String message) {
|
||||||
routingModes = modes;
|
routingModes = modes;
|
||||||
routingModesChecked = modesChecked;
|
routingModesChecked = modesChecked;
|
||||||
|
@ -439,74 +374,45 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
showDialog(DIALOG_ROUTINGMODES_ID);
|
showDialog(DIALOG_ROUTINGMODES_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void showModeConfigOverview(String message) {
|
public void showModeConfigOverview(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
showDialog(DIALOG_MODECONFIGOVERVIEW_ID);
|
showDialog(DIALOG_MODECONFIGOVERVIEW_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void selectVias(String[] items) {
|
public void selectVias(String[] items) {
|
||||||
availableVias = items;
|
availableVias = items;
|
||||||
selectedVias = new HashSet<String>(availableVias.length);
|
selectedVias = new HashSet<>(availableVias.length);
|
||||||
for (String via : items)
|
Collections.addAll(selectedVias, items);
|
||||||
selectedVias.add(via);
|
|
||||||
showDialog(DIALOG_VIASELECT_ID);
|
showDialog(DIALOG_VIASELECT_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void selectWaypoint(String[] items) {
|
public void selectWaypoint(String[] items) {
|
||||||
availableWaypoints = items;
|
availableWaypoints = items;
|
||||||
showNewDialog(DIALOG_PICKWAYPOINT_ID);
|
showNewDialog(DIALOG_PICKWAYPOINT_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void showWaypointDatabaseHelp() {
|
|
||||||
if (mBRouterView.canAccessSdCard) {
|
|
||||||
showNewDialog(DIALOG_SHOW_WP_HELP_ID);
|
|
||||||
} else {
|
|
||||||
showNewDialog(DIALOG_SHOW_API23_HELP_ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void showRepeatTimeoutHelp() {
|
public void showRepeatTimeoutHelp() {
|
||||||
showNewDialog(DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID);
|
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) {
|
public void selectNogos(List<OsmNodeNamed> nogoList) {
|
||||||
this.nogoList = nogoList;
|
this.nogoList = nogoList;
|
||||||
showDialog(DIALOG_NOGOSELECT_ID);
|
showDialog(DIALOG_NOGOSELECT_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Integer> dialogIds = new HashSet<Integer>();
|
|
||||||
|
|
||||||
private void showNewDialog(int id) {
|
private void showNewDialog(int id) {
|
||||||
if (dialogIds.contains(Integer.valueOf(id))) {
|
if (dialogIds.contains(id)) {
|
||||||
removeDialog(id);
|
removeDialog(id);
|
||||||
}
|
}
|
||||||
dialogIds.add(Integer.valueOf(id));
|
dialogIds.add(id);
|
||||||
showDialog(id);
|
showDialog(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String errorMessage;
|
|
||||||
private String title;
|
|
||||||
private int wpCount;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void showErrorMessage(String msg) {
|
public void showErrorMessage(String msg) {
|
||||||
errorMessage = msg;
|
errorMessage = msg;
|
||||||
showNewDialog(DIALOG_EXCEPTION_ID);
|
showNewDialog(DIALOG_EXCEPTION_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void showResultMessage(String title, String msg, int wpCount) {
|
public void showResultMessage(String title, String msg, int wpCount) {
|
||||||
errorMessage = msg;
|
errorMessage = msg;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
@ -514,48 +420,29 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
showNewDialog(DIALOG_SHOWRESULT_ID);
|
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
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.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();
|
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() {
|
public ArrayList<File> getStorageDirectories() {
|
||||||
ArrayList<File> list = null;
|
ArrayList<File> list = null;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
list = new ArrayList<File>(Arrays.asList(getExternalMediaDirs()));
|
list = new ArrayList<>(Arrays.asList(getExternalMediaDirs()));
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
} 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<>();
|
||||||
|
|
||||||
for (File f : list) {
|
if (list != null) {
|
||||||
if (f != null) {
|
for (File f : list) {
|
||||||
if (getStorageState(f).equals(Environment.MEDIA_MOUNTED))
|
if (f != null) {
|
||||||
res.add(f);
|
if (EnvironmentCompat.getStorageState(f).equals(Environment.MEDIA_MOUNTED))
|
||||||
|
res.add(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +475,7 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (requestCode == 0) {
|
if (requestCode == 0) {
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
package btools.routingapp;
|
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.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -10,26 +19,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
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 btools.router.OsmNodeNamed;
|
import btools.router.OsmNodeNamed;
|
||||||
|
|
||||||
|
@ -185,18 +177,7 @@ public class BRouterService extends Service {
|
||||||
|
|
||||||
private void readNogos(BRouterWorker worker, String baseDir) throws Exception {
|
private void readNogos(BRouterWorker worker, String baseDir) throws Exception {
|
||||||
// add nogos from waypoint database
|
// add nogos from waypoint database
|
||||||
int deviceLevel = android.os.Build.VERSION.SDK_INT;
|
CoordinateReader cor = CoordinateReader.obtainValidReader(baseDir, true);
|
||||||
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);
|
|
||||||
worker.nogoList = new ArrayList<OsmNodeNamed>(cor.nogopoints);
|
worker.nogoList = new ArrayList<OsmNodeNamed>(cor.nogopoints);
|
||||||
worker.nogoPolygonsList = new ArrayList<OsmNodeNamed>();
|
worker.nogoPolygonsList = new ArrayList<OsmNodeNamed>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,19 @@ package btools.routingapp;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
|
@ -26,7 +26,6 @@ import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -47,10 +46,11 @@ import btools.router.RoutingHelper;
|
||||||
import btools.util.CheapRuler;
|
import btools.util.CheapRuler;
|
||||||
|
|
||||||
public class BRouterView extends View {
|
public class BRouterView extends View {
|
||||||
|
|
||||||
|
private final int memoryClass;
|
||||||
RoutingEngine cr;
|
RoutingEngine cr;
|
||||||
private int imgw;
|
private int imgw;
|
||||||
private int imgh;
|
private int imgh;
|
||||||
|
|
||||||
private int centerLon;
|
private int centerLon;
|
||||||
private int centerLat;
|
private int centerLat;
|
||||||
private double scaleLon; // ilon -> pixel
|
private double scaleLon; // ilon -> pixel
|
||||||
|
@ -60,45 +60,35 @@ public class BRouterView extends View {
|
||||||
private List<OsmNodeNamed> nogoList;
|
private List<OsmNodeNamed> nogoList;
|
||||||
private List<OsmNodeNamed> nogoVetoList;
|
private List<OsmNodeNamed> nogoVetoList;
|
||||||
private OsmTrack rawTrack;
|
private OsmTrack rawTrack;
|
||||||
|
|
||||||
private File retryBaseDir;
|
private File retryBaseDir;
|
||||||
private File modesDir;
|
private File modesDir;
|
||||||
private File tracksDir;
|
private File tracksDir;
|
||||||
private File segmentDir;
|
private File segmentDir;
|
||||||
private File profileDir;
|
private File profileDir;
|
||||||
private String profilePath;
|
|
||||||
private String profileName;
|
private String profileName;
|
||||||
private String sourceHint;
|
|
||||||
private boolean waitingForSelection = false;
|
private boolean waitingForSelection = false;
|
||||||
private boolean waitingForMigration = false;
|
private boolean waitingForMigration = false;
|
||||||
private String rawTrackPath;
|
private String rawTrackPath;
|
||||||
private String oldMigrationPath;
|
private String oldMigrationPath;
|
||||||
|
private String trackOutfile;
|
||||||
private boolean needsViaSelection;
|
private boolean needsViaSelection;
|
||||||
private boolean needsNogoSelection;
|
private boolean needsNogoSelection;
|
||||||
private boolean needsWaypointSelection;
|
private boolean needsWaypointSelection;
|
||||||
|
|
||||||
private WpDatabaseScanner dataBaseScanner;
|
|
||||||
|
|
||||||
private long lastDataTime = System.currentTimeMillis();
|
private long lastDataTime = System.currentTimeMillis();
|
||||||
|
|
||||||
private CoordinateReader cor;
|
private CoordinateReader cor;
|
||||||
|
|
||||||
private int[] imgPixels;
|
private int[] imgPixels;
|
||||||
|
private long lastTs = System.currentTimeMillis();
|
||||||
private int memoryClass;
|
private long startTime = 0L;
|
||||||
|
|
||||||
public boolean canAccessSdCard;
|
|
||||||
|
|
||||||
public void stopRouting() {
|
|
||||||
if (cr != null) cr.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BRouterView(Context context, int memoryClass) {
|
public BRouterView(Context context, int memoryClass) {
|
||||||
super(context);
|
super(context);
|
||||||
this.memoryClass = memoryClass;
|
this.memoryClass = memoryClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopRouting() {
|
||||||
|
if (cr != null) cr.terminate();
|
||||||
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
// get base dir from private file
|
// get base dir from private file
|
||||||
|
@ -114,29 +104,27 @@ public class BRouterView extends View {
|
||||||
|
|
||||||
// don't ask twice
|
// don't ask twice
|
||||||
String version = "v" + getContext().getString(R.string.app_version);
|
String version = "v" + getContext().getString(R.string.app_version);
|
||||||
File vFile = new File(brd, "profiles2/"+version );
|
File vFile = new File(brd, "profiles2/" + version);
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q
|
if (vFile.exists()) {
|
||||||
&& vFile.exists()) {
|
|
||||||
startSetup(baseDir, false);
|
startSetup(baseDir, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String message = "(previous basedir " + baseDir + " has to migrate )";
|
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;
|
waitingForSelection = true;
|
||||||
waitingForMigration = true;
|
waitingForMigration = true;
|
||||||
oldMigrationPath = brd.getAbsolutePath();
|
oldMigrationPath = brd.getAbsolutePath();
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
startSetup(baseDir, false);
|
startSetup(baseDir, false);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String message = baseDir == null ? "(no basedir configured previously)" : "(previous basedir " + baseDir
|
String message = baseDir == null ? "(no basedir configured previously)" : "(previous basedir " + baseDir
|
||||||
+ (bdValid ? " does not contain 'brouter' subfolder)" : " is not valid)");
|
+ (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;
|
waitingForSelection = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString();
|
String msg = e instanceof IllegalArgumentException ? e.getMessage() : e.toString();
|
||||||
|
@ -168,7 +156,7 @@ public class BRouterView extends View {
|
||||||
retryBaseDir = baseDir;
|
retryBaseDir = baseDir;
|
||||||
ActivityCompat.requestPermissions((BRouterActivity) getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
ActivityCompat.requestPermissions((BRouterActivity) getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
||||||
} else {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -180,24 +168,7 @@ public class BRouterView extends View {
|
||||||
String basedir = baseDir.getAbsolutePath();
|
String basedir = baseDir.getAbsolutePath();
|
||||||
AppLogger.log("using basedir: " + basedir);
|
AppLogger.log("using basedir: " + basedir);
|
||||||
|
|
||||||
String version = "v" + getContext().getString(R.string.app_version);
|
populateBasedir(basedir);
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// new init is done move old files
|
// new init is done move old files
|
||||||
if (waitingForMigration) {
|
if (waitingForMigration) {
|
||||||
|
@ -207,23 +178,11 @@ public class BRouterView extends View {
|
||||||
waitingForMigration = false;
|
waitingForMigration = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int deviceLevel = Build.VERSION.SDK_INT;
|
cor = CoordinateReader.obtainValidReader(basedir);
|
||||||
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);
|
|
||||||
|
|
||||||
wpList = cor.waypoints;
|
wpList = cor.waypoints;
|
||||||
nogoList = cor.nogopoints;
|
nogoList = cor.nogopoints;
|
||||||
nogoVetoList = new ArrayList<OsmNodeNamed>();
|
nogoVetoList = new ArrayList<>();
|
||||||
|
|
||||||
sourceHint = "(dev/trgt=" + deviceLevel + "/" + targetSdkVersion + " coordinate-source: " + cor.basedir + cor.rootdir + ")";
|
|
||||||
|
|
||||||
needsViaSelection = wpList.size() > 2;
|
needsViaSelection = wpList.size() > 2;
|
||||||
needsNogoSelection = nogoList.size() > 0;
|
needsNogoSelection = nogoList.size() > 0;
|
||||||
|
@ -232,40 +191,23 @@ public class BRouterView extends View {
|
||||||
if (cor.tracksdir != null) {
|
if (cor.tracksdir != null) {
|
||||||
tracksDir = new File(cor.basedir, cor.tracksdir);
|
tracksDir = new File(cor.basedir, cor.tracksdir);
|
||||||
assertDirectoryExists("track directory", tracksDir, null, null);
|
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) {
|
if (tracksDir == null) {
|
||||||
tracksDir = new File(basedir, "brouter"); // fallback
|
tracksDir = new File(basedir, "brouter"); // fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] fileNames = profileDir.list();
|
String[] fileNames = profileDir.list();
|
||||||
ArrayList<String> profiles = new ArrayList<String>();
|
ArrayList<String> profiles = new ArrayList<>();
|
||||||
|
|
||||||
boolean lookupsFound = false;
|
boolean lookupsFound = false;
|
||||||
for (String fileName : fileNames) {
|
if (fileNames != null) {
|
||||||
if (fileName.endsWith(".brf")) {
|
for (String fileName : fileNames) {
|
||||||
profiles.add(fileName.substring(0, fileName.length() - 4));
|
if (fileName.endsWith(".brf")) {
|
||||||
|
profiles.add(fileName.substring(0, fileName.length() - 4));
|
||||||
|
}
|
||||||
|
if (fileName.equals("lookups.dat"))
|
||||||
|
lookupsFound = true;
|
||||||
}
|
}
|
||||||
if (fileName.equals("lookups.dat"))
|
|
||||||
lookupsFound = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a "last timeout" dummy profile
|
// add a "last timeout" dummy profile
|
||||||
|
@ -304,38 +246,59 @@ public class BRouterView extends View {
|
||||||
waitingForSelection = true;
|
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) {
|
private void moveFolders(String oldMigrationPath, String basedir) {
|
||||||
File oldDir = new File(oldMigrationPath);
|
File oldDir = new File(oldMigrationPath);
|
||||||
File[] oldFiles = oldDir.listFiles();
|
File[] oldFiles = oldDir.listFiles();
|
||||||
for (File f : oldFiles) {
|
if (oldFiles != null) {
|
||||||
if (f.isDirectory()) {
|
for (File f : oldFiles) {
|
||||||
int index = f.getAbsolutePath().lastIndexOf("/");
|
if (f.isDirectory()) {
|
||||||
String tmpdir = basedir + f.getAbsolutePath().substring(index);
|
int index = f.getAbsolutePath().lastIndexOf("/");
|
||||||
moveFolders(f.getAbsolutePath(), tmpdir);
|
String tmpdir = basedir + f.getAbsolutePath().substring(index);
|
||||||
} else {
|
moveFolders(f.getAbsolutePath(), tmpdir);
|
||||||
if (!f.getName().startsWith("v1.6")) {
|
} else {
|
||||||
moveFile(oldMigrationPath, f.getName(), basedir);
|
if (!f.getName().startsWith("v1.6")) {
|
||||||
|
moveFile(oldMigrationPath, f.getName(), basedir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
try {
|
||||||
|
|
||||||
//create output directory if it doesn't exist
|
//create output directory if it doesn't exist
|
||||||
File dir = new File(outputPath);
|
File dir = new File(outputPath);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
dir.mkdirs();
|
dir.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in = new FileInputStream(new File(inputPath, inputFile));
|
||||||
in = new FileInputStream(inputPath + "/" + inputFile);
|
out = new FileOutputStream(new File(outputPath, inputFile));
|
||||||
out = new FileOutputStream(outputPath + "/" + inputFile);
|
|
||||||
|
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int read;
|
int read;
|
||||||
|
@ -343,23 +306,22 @@ public class BRouterView extends View {
|
||||||
out.write(buffer, 0, read);
|
out.write(buffer, 0, read);
|
||||||
}
|
}
|
||||||
in.close();
|
in.close();
|
||||||
in = null;
|
|
||||||
|
|
||||||
// write the output file
|
// write the output file
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
out = null;
|
|
||||||
|
|
||||||
// delete the original file
|
} catch (FileNotFoundException fileNotFoundException) {
|
||||||
new File(inputPath + "/" + inputFile).delete();
|
Log.e("tag", fileNotFoundException.getMessage());
|
||||||
|
|
||||||
|
|
||||||
} catch (FileNotFoundException fnfe1) {
|
|
||||||
Log.e("tag", fnfe1.getMessage());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("tag", e.getMessage());
|
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() {
|
public boolean hasUpToDateLookups() {
|
||||||
|
@ -374,7 +336,7 @@ public class BRouterView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateViaList(Set<String> selectedVias) {
|
public void updateViaList(Set<String> selectedVias) {
|
||||||
ArrayList<OsmNodeNamed> filtered = new ArrayList<OsmNodeNamed>(wpList.size());
|
ArrayList<OsmNodeNamed> filtered = new ArrayList<>(wpList.size());
|
||||||
for (OsmNodeNamed n : wpList) {
|
for (OsmNodeNamed n : wpList) {
|
||||||
String name = n.name;
|
String name = n.name;
|
||||||
if ("from".equals(name) || "to".equals(name) || selectedVias.contains(name))
|
if ("from".equals(name) || "to".equals(name) || selectedVias.contains(name))
|
||||||
|
@ -399,7 +361,7 @@ public class BRouterView extends View {
|
||||||
try {
|
try {
|
||||||
cor.readAllPoints();
|
cor.readAllPoints();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
msg = "Error reading waypoints: " + e.toString();
|
msg = "Error reading waypoints: " + e;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = cor.allpoints.size();
|
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() {
|
public void finishWaypointSelection() {
|
||||||
needsWaypointSelection = false;
|
needsWaypointSelection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<OsmNodeNamed> readWpList(BufferedReader br, boolean isNogo) throws Exception {
|
private List<OsmNodeNamed> readWpList(BufferedReader br, boolean isNogo) throws Exception {
|
||||||
int cnt = Integer.parseInt(br.readLine());
|
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++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
OsmNodeNamed wp = OsmNodeNamed.decodeNogo(br.readLine());
|
OsmNodeNamed wp = OsmNodeNamed.decodeNogo(br.readLine());
|
||||||
wp.isNogo = isNogo;
|
wp.isNogo = isNogo;
|
||||||
|
@ -480,7 +431,7 @@ public class BRouterView extends View {
|
||||||
rawTrackPath = modesDir + "/remote_rawtrack.dat";
|
rawTrackPath = modesDir + "/remote_rawtrack.dat";
|
||||||
}
|
}
|
||||||
|
|
||||||
profilePath = profileDir + "/" + profile + ".brf";
|
String profilePath = profileDir + "/" + profile + ".brf";
|
||||||
profileName = profile;
|
profileName = profile;
|
||||||
|
|
||||||
if (needsViaSelection) {
|
if (needsViaSelection) {
|
||||||
|
@ -499,15 +450,15 @@ public class BRouterView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsWaypointSelection) {
|
if (needsWaypointSelection) {
|
||||||
String msg;
|
StringBuilder msg;
|
||||||
if (wpList.size() == 0) {
|
if (wpList.size() == 0) {
|
||||||
msg = "Expecting waypoint selection\n" + sourceHint;
|
msg = new StringBuilder("Expecting waypoint selection\n" + "(coordinate-source: " + cor.basedir + cor.rootdir + ")");
|
||||||
} else {
|
} else {
|
||||||
msg = "current waypoint selection:\n";
|
msg = new StringBuilder("current waypoint selection:\n");
|
||||||
for (int i = 0; i < wpList.size(); i++)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +519,7 @@ public class BRouterView extends View {
|
||||||
// for profile remote, use ref-track logic same as service interface
|
// for profile remote, use ref-track logic same as service interface
|
||||||
rc.rawTrackPath = rawTrackPath;
|
rc.rawTrackPath = rawTrackPath;
|
||||||
|
|
||||||
cr = new RoutingEngine(tracksDir.getAbsolutePath()+"/brouter", null, segmentDir, wpList, rc);
|
cr = new RoutingEngine(tracksDir.getAbsolutePath() + "/brouter", null, segmentDir, wpList, rc);
|
||||||
cr.start();
|
cr.start();
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
|
@ -587,7 +538,7 @@ public class BRouterView extends View {
|
||||||
File vtag = new File(path, versionTag);
|
File vtag = new File(path, versionTag);
|
||||||
try {
|
try {
|
||||||
exists = !vtag.createNewFile();
|
exists = !vtag.createNewFile();
|
||||||
} catch (IOException io) {
|
} catch (IOException ignored) {
|
||||||
} // well..
|
} // well..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +559,7 @@ public class BRouterView extends View {
|
||||||
}
|
}
|
||||||
String name = ze.getName();
|
String name = ze.getName();
|
||||||
File outfile = new File(path, name);
|
File outfile = new File(path, name);
|
||||||
if (!outfile.exists()) {
|
if (!outfile.exists() && outfile.getParentFile() != null) {
|
||||||
outfile.getParentFile().mkdirs();
|
outfile.getParentFile().mkdirs();
|
||||||
FileOutputStream fos = new FileOutputStream(outfile);
|
FileOutputStream fos = new FileOutputStream(outfile);
|
||||||
|
|
||||||
|
@ -656,7 +607,7 @@ public class BRouterView extends View {
|
||||||
int ir = (int) (n.radius * scaleMeter2Pixel);
|
int ir = (int) (n.radius * scaleMeter2Pixel);
|
||||||
if (ir > minradius) {
|
if (ir > minradius) {
|
||||||
Paint paint = new Paint();
|
Paint paint = new Paint();
|
||||||
paint.setColor(Color.RED);
|
paint.setColor(color);
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
canvas.drawCircle((float) x, (float) y, (float) ir, paint);
|
canvas.drawCircle((float) x, (float) y, (float) ir, paint);
|
||||||
}
|
}
|
||||||
|
@ -703,9 +654,6 @@ public class BRouterView extends View {
|
||||||
lastDataTime += 4000; // give time for the toast before exiting
|
lastDataTime += 4000; // give time for the toast before exiting
|
||||||
}
|
}
|
||||||
|
|
||||||
private long lastTs = System.currentTimeMillis();
|
|
||||||
private long startTime = 0L;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
try {
|
try {
|
||||||
|
@ -717,58 +665,14 @@ public class BRouterView extends View {
|
||||||
cr = null;
|
cr = null;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
((BRouterActivity) getContext()).showErrorMessage(t.toString());
|
((BRouterActivity) getContext()).showErrorMessage(t.toString());
|
||||||
waitingForSelection = true;
|
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) {
|
private void _onDraw(Canvas canvas) {
|
||||||
if (dataBaseScanner != null) {
|
|
||||||
showDatabaseScanning(canvas);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waitingForSelection)
|
if (waitingForSelection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -780,7 +684,7 @@ public class BRouterView extends View {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(sleeptime);
|
Thread.sleep(sleeptime);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
lastTs = System.currentTimeMillis();
|
lastTs = System.currentTimeMillis();
|
||||||
|
|
||||||
|
@ -788,9 +692,6 @@ public class BRouterView extends View {
|
||||||
if (cr != null) {
|
if (cr != null) {
|
||||||
if (cr.getErrorMessage() != null) {
|
if (cr.getErrorMessage() != null) {
|
||||||
((BRouterActivity) getContext()).showErrorMessage(cr.getErrorMessage());
|
((BRouterActivity) getContext()).showErrorMessage(cr.getErrorMessage());
|
||||||
cr = null;
|
|
||||||
waitingForSelection = true;
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
String memstat = memoryClass + "mb pathPeak " + ((cr.getPathPeak() + 500) / 1000) + "k";
|
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()
|
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";
|
title += " / " + cr.getAlternativeIndex() + ". Alternative";
|
||||||
|
|
||||||
((BRouterActivity) getContext()).showResultMessage(title, result, rawTrackPath == null ? -1 : -3);
|
((BRouterActivity) getContext()).showResultMessage(title, result, rawTrackPath == null ? -1 : -3);
|
||||||
cr = null;
|
trackOutfile = cr.getOutfile();
|
||||||
waitingForSelection = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
cr = null;
|
||||||
|
waitingForSelection = true;
|
||||||
|
return;
|
||||||
} else if (System.currentTimeMillis() > lastDataTime) {
|
} else if (System.currentTimeMillis() > lastDataTime) {
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -824,17 +726,18 @@ public class BRouterView extends View {
|
||||||
paintPosition(openSet[si], openSet[si + 1], 0xffffff, 1);
|
paintPosition(openSet[si], openSet[si + 1], 0xffffff, 1);
|
||||||
}
|
}
|
||||||
// paint nogos on top (red)
|
// paint nogos on top (red)
|
||||||
|
int minradius = 4;
|
||||||
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
|
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
|
||||||
OsmNodeNamed n = nogoList.get(ngi);
|
OsmNodeNamed n = nogoList.get(ngi);
|
||||||
int color = 0xff0000;
|
int color = 0xff0000;
|
||||||
paintPosition(n.ilon, n.ilat, color, 4);
|
paintPosition(n.ilon, n.ilat, color, minradius);
|
||||||
}
|
}
|
||||||
|
|
||||||
// paint start/end/vias on top (yellow/green/blue)
|
// paint start/end/vias on top (yellow/green/blue)
|
||||||
for (int wpi = 0; wpi < wpList.size(); wpi++) {
|
for (int wpi = 0; wpi < wpList.size(); wpi++) {
|
||||||
OsmNodeNamed n = wpList.get(wpi);
|
OsmNodeNamed n = wpList.get(wpi);
|
||||||
int color = wpi == 0 ? 0xffff00 : wpi < wpList.size() - 1 ? 0xff : 0xff00;
|
int color = wpi == 0 ? 0xffff00 : wpi < wpList.size() - 1 ? 0xff : 0xff00;
|
||||||
paintPosition(n.ilon, n.ilat, color, 4);
|
paintPosition(n.ilon, n.ilat, color, minradius);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.drawBitmap(imgPixels, 0, imgw, (float) 0., (float) 0., imgw, imgh, false, null);
|
canvas.drawBitmap(imgPixels, 0, imgw, (float) 0., (float) 0., imgw, imgh, false, null);
|
||||||
|
@ -843,10 +746,10 @@ public class BRouterView extends View {
|
||||||
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
|
for (int ngi = 0; ngi < nogoList.size(); ngi++) {
|
||||||
OsmNodeNamed n = nogoList.get(ngi);
|
OsmNodeNamed n = nogoList.get(ngi);
|
||||||
if (n instanceof OsmNogoPolygon) {
|
if (n instanceof OsmNogoPolygon) {
|
||||||
paintPolygon(canvas, (OsmNogoPolygon) n, 4);
|
paintPolygon(canvas, (OsmNogoPolygon) n, minradius);
|
||||||
} else {
|
} else {
|
||||||
int color = 0xff0000;
|
int color = Color.RED;
|
||||||
paintCircle(canvas, n, color, 4);
|
paintCircle(canvas, n, color, minradius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,42 +768,6 @@ public class BRouterView extends View {
|
||||||
invalidate();
|
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) {
|
private void writeRawTrackToMode(String mode) {
|
||||||
writeRawTrackToPath(modesDir + "/" + mode + "_rawtrack.dat");
|
writeRawTrackToPath(modesDir + "/" + mode + "_rawtrack.dat");
|
||||||
}
|
}
|
||||||
|
@ -909,7 +776,7 @@ public class BRouterView extends View {
|
||||||
if (rawTrack != null) {
|
if (rawTrack != null) {
|
||||||
try {
|
try {
|
||||||
rawTrack.writeBinary(rawTrackPath);
|
rawTrack.writeBinary(rawTrackPath);
|
||||||
} catch (Exception e) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new File(rawTrackPath).delete();
|
new File(rawTrackPath).delete();
|
||||||
|
@ -928,7 +795,7 @@ public class BRouterView extends View {
|
||||||
|
|
||||||
public void configureService(String[] routingModes, boolean[] checkedModes) {
|
public void configureService(String[] routingModes, boolean[] checkedModes) {
|
||||||
// read in current config
|
// read in current config
|
||||||
TreeMap<String, ServiceModeConfig> map = new TreeMap<String, ServiceModeConfig>();
|
TreeMap<String, ServiceModeConfig> map = new TreeMap<>();
|
||||||
BufferedReader br = null;
|
BufferedReader br = null;
|
||||||
String modesFile = modesDir + "/serviceconfig.dat";
|
String modesFile = modesDir + "/serviceconfig.dat";
|
||||||
try {
|
try {
|
||||||
|
@ -940,12 +807,12 @@ public class BRouterView extends View {
|
||||||
ServiceModeConfig smc = new ServiceModeConfig(line);
|
ServiceModeConfig smc = new ServiceModeConfig(line);
|
||||||
map.put(smc.mode, smc);
|
map.put(smc.mode, smc);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception ignored) {
|
||||||
} finally {
|
} finally {
|
||||||
if (br != null)
|
if (br != null)
|
||||||
try {
|
try {
|
||||||
br.close();
|
br.close();
|
||||||
} catch (Exception ee) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,27 +838,29 @@ public class BRouterView extends View {
|
||||||
for (ServiceModeConfig smc : map.values()) {
|
for (ServiceModeConfig smc : map.values()) {
|
||||||
bw.write(smc.toLine());
|
bw.write(smc.toLine());
|
||||||
bw.write('\n');
|
bw.write('\n');
|
||||||
msg.append(smc.toString()).append('\n');
|
msg.append(smc).append('\n');
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception ignored) {
|
||||||
} finally {
|
} finally {
|
||||||
if (bw != null)
|
if (bw != null)
|
||||||
try {
|
try {
|
||||||
bw.close();
|
bw.close();
|
||||||
} catch (Exception ee) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((BRouterActivity) getContext()).showModeConfigOverview(msg.toString());
|
((BRouterActivity) getContext()).showModeConfigOverview(msg.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readSingleLineFile(File f) {
|
public void shareTrack() {
|
||||||
try (FileInputStream fis = new FileInputStream(f);
|
File track = new File(trackOutfile);
|
||||||
InputStreamReader isr = new InputStreamReader(fis);
|
// Copy file to cache to ensure FileProvider allows sharing the file
|
||||||
BufferedReader br = new BufferedReader(isr)) {
|
File cacheDir = getContext().getCacheDir();
|
||||||
return br.readLine();
|
copyFile(track.getParent(), track.getName(), cacheDir.getAbsolutePath());
|
||||||
} catch (Exception e) {
|
Intent intent = new Intent();
|
||||||
return null;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
package btools.routingapp;
|
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.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.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -10,47 +20,182 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import android.os.Environment;
|
|
||||||
|
|
||||||
import btools.router.OsmNodeNamed;
|
import btools.router.OsmNodeNamed;
|
||||||
import btools.router.RoutingHelper;
|
import btools.router.OsmNogoPolygon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read coordinates from a gpx-file
|
* 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> waypoints;
|
||||||
public List<OsmNodeNamed> nogopoints;
|
public List<OsmNodeNamed> nogopoints;
|
||||||
public String basedir;
|
public String basedir;
|
||||||
public String rootdir;
|
public String rootdir;
|
||||||
public String tracksdir;
|
public String tracksdir;
|
||||||
|
|
||||||
private boolean nogosOnly;
|
|
||||||
|
|
||||||
private Map<String, Map<String, OsmNodeNamed>> allpointsMap;
|
|
||||||
public List<OsmNodeNamed> allpoints;
|
public List<OsmNodeNamed> allpoints;
|
||||||
|
private boolean nogosOnly;
|
||||||
|
private Map<String, Map<String, OsmNodeNamed>> allpointsMap;
|
||||||
private HashMap<String, OsmNodeNamed> pointmap;
|
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) {
|
public CoordinateReader(String basedir) {
|
||||||
this.basedir = 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 {
|
public void readAllPoints() throws Exception {
|
||||||
allpointsMap = new TreeMap<String, Map<String, OsmNodeNamed>>();
|
allpointsMap = new TreeMap<>();
|
||||||
readFromTo();
|
readFromTo();
|
||||||
allpoints = new ArrayList<OsmNodeNamed>();
|
allpoints = new ArrayList<>();
|
||||||
Set<String> names = new HashSet<String>();
|
Set<String> names = new HashSet<>();
|
||||||
for (String category : allpointsMap.keySet()) {
|
for (String category : allpointsMap.keySet()) {
|
||||||
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
|
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
|
||||||
if (cat.size() < 101) {
|
if (cat != null && cat.size() < 101) {
|
||||||
for (OsmNodeNamed wp : cat.values()) {
|
for (OsmNodeNamed wp : cat.values()) {
|
||||||
if (names.add(wp.name)) {
|
if (names.add(wp.name)) {
|
||||||
allpoints.add(wp);
|
allpoints.add(wp);
|
||||||
|
@ -67,14 +212,13 @@ public abstract class CoordinateReader {
|
||||||
/*
|
/*
|
||||||
* read the from, to and via-positions from a gpx-file
|
* read the from, to and via-positions from a gpx-file
|
||||||
*/
|
*/
|
||||||
public void readFromTo() throws Exception {
|
public void readFromTo() throws IOException {
|
||||||
pointmap = new HashMap<String, OsmNodeNamed>();
|
pointmap = new HashMap<>();
|
||||||
waypoints = new ArrayList<OsmNodeNamed>();
|
waypoints = new ArrayList<>();
|
||||||
nogopoints = new ArrayList<OsmNodeNamed>();
|
nogopoints = new ArrayList<>();
|
||||||
readPointmap();
|
readPointmap();
|
||||||
boolean fromToMissing = false;
|
boolean fromToMissing = false;
|
||||||
for (int i = 0; i < posnames.length; i++) {
|
for (String name : posnames) {
|
||||||
String name = posnames[i];
|
|
||||||
OsmNodeNamed n = pointmap.get(name);
|
OsmNodeNamed n = pointmap.get(name);
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
waypoints.add(n);
|
waypoints.add(n);
|
||||||
|
@ -91,7 +235,7 @@ public abstract class CoordinateReader {
|
||||||
if (category == null) category = "";
|
if (category == null) category = "";
|
||||||
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
|
Map<String, OsmNodeNamed> cat = allpointsMap.get(category);
|
||||||
if (cat == null) {
|
if (cat == null) {
|
||||||
cat = new TreeMap<String, OsmNodeNamed>();
|
cat = new TreeMap<>();
|
||||||
allpointsMap.put(category, cat);
|
allpointsMap.put(category, cat);
|
||||||
}
|
}
|
||||||
if (cat.size() < 101) {
|
if (cat.size() < 101) {
|
||||||
|
@ -101,8 +245,8 @@ public abstract class CoordinateReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isKnown = false;
|
boolean isKnown = false;
|
||||||
for (int i = 0; i < posnames.length; i++) {
|
for (String posname : posnames) {
|
||||||
if (posnames[i].equals(n.name)) {
|
if (posname.equals(n.name)) {
|
||||||
isKnown = true;
|
isKnown = true;
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
5
brouter-routing-app/src/main/res/xml/filepaths.xml
Normal file
5
brouter-routing-app/src/main/res/xml/filepaths.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<paths>
|
||||||
|
<cache-path
|
||||||
|
name="cache"
|
||||||
|
path="." />
|
||||||
|
</paths>
|
Loading…
Reference in a new issue