Remove app specific coordinate readers

This commit is contained in:
Manuel Fuhr 2022-05-07 08:04:13 +02:00
parent 924a33ccb5
commit 01ad4dc09a
7 changed files with 23 additions and 448 deletions

View file

@ -55,7 +55,6 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
private String[] availableWaypoints; private String[] availableWaypoints;
private String[] routingModes; private String[] routingModes;
private boolean[] routingModesChecked; private boolean[] routingModesChecked;
private String defaultbasedir = null;
private String message = null; private String message = null;
private String[] availableVias; private String[] availableVias;
private Set<String> selectedVias; private Set<String> selectedVias;
@ -206,7 +205,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) {
@ -342,8 +341,7 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat
} }
} }
public void selectBasedir(ArrayList<File> items, String defaultBasedir, String message) { public void selectBasedir(ArrayList<File> items, String message) {
this.defaultbasedir = defaultBasedir;
this.message = message; this.message = message;
availableBasedirs = items; availableBasedirs = items;
ArrayList<Long> dirFreeSizes = new ArrayList<>(); ArrayList<Long> dirFreeSizes = new ArrayList<>();

View file

@ -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>();
} }

View file

@ -7,8 +7,6 @@ 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;
@ -48,7 +46,7 @@ import btools.util.CheapRuler;
public class BRouterView extends View { public class BRouterView extends View {
public boolean canAccessSdCard; private final int memoryClass;
RoutingEngine cr; RoutingEngine cr;
private int imgw; private int imgw;
private int imgh; private int imgh;
@ -67,7 +65,6 @@ public class BRouterView extends View {
private File segmentDir; private File segmentDir;
private File profileDir; private File profileDir;
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;
@ -78,7 +75,6 @@ public class BRouterView extends View {
private long lastDataTime = System.currentTimeMillis(); private long lastDataTime = System.currentTimeMillis();
private CoordinateReader cor; private CoordinateReader cor;
private int[] imgPixels; private int[] imgPixels;
private final int memoryClass;
private long lastTs = System.currentTimeMillis(); private long lastTs = System.currentTimeMillis();
private long startTime = 0L; private long startTime = 0L;
@ -113,7 +109,7 @@ public class BRouterView extends View {
} }
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();
@ -126,7 +122,7 @@ public class BRouterView extends View {
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();
@ -158,7 +154,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,21 +176,12 @@ 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 = Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || Environment.isExternalStorageLegacy();
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<>(); 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;
needsWaypointSelection = wpList.size() == 0; needsWaypointSelection = wpList.size() == 0;
@ -483,7 +470,7 @@ public class BRouterView extends View {
if (needsWaypointSelection) { if (needsWaypointSelection) {
StringBuilder msg; StringBuilder msg;
if (wpList.size() == 0) { if (wpList.size() == 0) {
msg = new StringBuilder("Expecting waypoint selection\n" + sourceHint); msg = new StringBuilder("Expecting waypoint selection\n" + "(coordinate-source: " + cor.basedir + cor.rootdir + ")");
} else { } else {
msg = new StringBuilder("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++)
@ -798,42 +785,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<>();
basedirGuesses.add(basedir.getAbsolutePath());
if (bd2.exists()) {
basedir = bd2;
basedirGuesses.add(basedir.getAbsolutePath());
}
ArrayList<CoordinateReader> rl = new ArrayList<>();
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");
} }

View file

@ -1,8 +1,6 @@
package btools.routingapp; package btools.routingapp;
import java.io.File;
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,10 +8,7 @@ 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;
/** /**
* Read coordinates from a gpx-file * Read coordinates from a gpx-file
@ -125,68 +120,12 @@ public abstract class CoordinateReader {
protected abstract void readPointmap() throws Exception; protected abstract void readPointmap() throws Exception;
public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard) throws Exception { public static CoordinateReader obtainValidReader(String basedir) throws Exception {
return obtainValidReader(basedir, segmentDir, canAccessSdCard, false); return obtainValidReader(basedir, false);
} }
public static CoordinateReader obtainValidReader(String basedir, File segmentDir, boolean canAccessSdCard, boolean nogosOnly) throws Exception { public static CoordinateReader obtainValidReader(String basedir, boolean nogosOnly) throws Exception {
CoordinateReader cor = null; CoordinateReader cor = new CoordinateReaderInternal(basedir);
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.nogosOnly = nogosOnly;
cor.readFromTo(); cor.readFromTo();
return cor; return cor;

View file

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

View file

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

View file

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