Add brouter service

This commit is contained in:
vshcherb 2014-01-11 23:52:31 +01:00
parent b3967f01c6
commit d72bd93b3c
5 changed files with 180 additions and 6 deletions

View file

@ -0,0 +1,23 @@
package btools.routingapp;
interface IBRouterService {
//param params--> Map of params:
// "pathToFileResult"-->String with the path to where the result must be saved, including file name and extension
// -->if null, the track is passed via the return argument
// "maxRunningTime"-->String with a number of seconds for the routing timeout, default = 60
// "trackFormat"-->[kml|gpx] default = gpx
// "lats"-->double[] array of latitudes; 2 values at least.
// "lons"-->double[] array of longitudes; 2 values at least.
// "nogoLats"-->double[] array of nogo latitudes; may be null.
// "nogoLons"-->double[] array of nogo longitudes; may be null.
// "nogoRadi"-->double[] array of nogo radius in meters; may be null.
// "fast"-->[0|1]
// "v"-->[motorcar|bicycle|foot]
//return null if all ok and no path given, the track if ok and path given, an error message if it was wrong
//call in a background thread, heavy task!
String getTrackFromParams(in Bundle params);
}

View file

@ -76,11 +76,12 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
}
registerListPreference(settings.AUTO_FOLLOW_ROUTE, screen, entries, intValues);
entries = new String[RouteService.values().length];
RouteService[] vls = RouteService.getAvailableRouters(this);
entries = new String[vls.length];
for(int i=0; i<entries.length; i++){
entries[i] = RouteService.values()[i].getName();
entries[i] = vls[i].getName();
}
registerListPreference(settings.ROUTER_SERVICE, screen, entries, RouteService.values());
registerListPreference(settings.ROUTER_SERVICE, screen, entries, vls);
routerServicePreference = (ListPreference) screen.findPreference(settings.ROUTER_SERVICE.getId());

View file

@ -279,7 +279,7 @@ public class NavigateAction {
}
private void updateTooLongDistance(final Location start, final TargetPointsHelper targets, View view, ApplicationMode appMode) {
boolean osmandRouter = mapActivity.getMyApplication().getSettings().ROUTER_SERVICE.getModeValue(appMode)== RouteService.OSMAND;
boolean osmandRouter = mapActivity.getMyApplication().getSettings().ROUTER_SERVICE.getModeValue(appMode) == RouteService.OSMAND;
TextView textView = (TextView) view.findViewById(R.id.ValidateTextView);
if(osmandRouter && targets.hasLongDistancesInBetween(start, 150000)) {
textView.setText(R.string.route_is_too_long);

View file

@ -5,6 +5,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@ -59,13 +60,24 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParserException;
import btools.routingapp.IBRouterService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
public class RouteProvider {
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(RouteProvider.class);
private static final String OSMAND_ROUTER = "OsmAndRouter";
public enum RouteService {
OSMAND("OsmAnd (offline)"), YOURS("YOURS"), ORS("OpenRouteService (outdated map data)"), OSRM("OSRM (only car)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
OSMAND("OsmAnd (offline)"), YOURS("YOURS"),
ORS("OpenRouteService (outdated map data)"), OSRM("OSRM (only car)"),
BROUTER("BRouter (offline)");
private final String name;
private RouteService(String name){
this.name = name;
@ -73,6 +85,35 @@ public class RouteProvider {
public String getName() {
return name;
}
public boolean isOnline(){
return this != OSMAND && this != BROUTER;
}
boolean isAvailable(Context ctx) {
if (this == BROUTER) {
try {
BRouterServiceConnection c = BRouterServiceConnection.connect(ctx);
if(c != null) {
c.disconnect(ctx);
return true;
}
} catch (Exception e) {
return false;
}
}
return true;
}
public static RouteService[] getAvailableRouters(Context ctx){
List<RouteService> list = new ArrayList<RouteProvider.RouteService>();
for(RouteService r : values()) {
if(r.isAvailable(ctx)) {
list.add(r);
}
}
return list.toArray(new RouteService[list.size()]);
}
}
public RouteProvider(){
@ -187,6 +228,8 @@ public class RouteProvider {
res = findOSRMRoute(params);
} else if (params.type == RouteService.OSMAND) {
res = findVectorMapsRoute(params);
} else if (params.type == RouteService.BROUTER) {
res = findBROUTERRoute(params);
} else {
res = findCloudMadeRoute(params);
}
@ -830,7 +873,114 @@ public class RouteProvider {
}
static class BRouterServiceConnection implements ServiceConnection {
IBRouterService brouterService;
public void onServiceConnected(ComponentName className, IBinder boundService) {
brouterService = IBRouterService.Stub.asInterface((IBinder) boundService);
}
public void onServiceDisconnected(ComponentName className) {
brouterService = null;
}
public void disconnect(Context ctx){
ctx.unbindService(this);
}
public static BRouterServiceConnection connect(Context ctx){
BRouterServiceConnection conn = new BRouterServiceConnection();
Intent intent = new Intent();
intent.setClassName("btools.routingapp", "btools.routingapp.BRouterService");
boolean hasBRouter = ctx.bindService(intent, conn, Context.BIND_AUTO_CREATE);
if(!hasBRouter){
conn = null;
}
return conn;
}
};
protected RouteCalculationResult findBROUTERRoute(RouteCalculationParams params) throws MalformedURLException,
IOException, ParserConfigurationException, FactoryConfigurationError, SAXException {
double[] lats = new double[] { params.start.getLatitude(), params.end.getLatitude() };
double[] lons = new double[] { params.start.getLongitude(), params.end.getLongitude() };
String mode;
if (ApplicationMode.PEDESTRIAN == params.mode) {
mode = "foot"; //$NON-NLS-1$
} else if (ApplicationMode.BICYCLE == params.mode) {
mode = "bicycle"; //$NON-NLS-1$
} else {
mode = "motorcar"; //$NON-NLS-1$
}
Bundle bpars = new Bundle();
bpars.putDoubleArray("lats", lats);
bpars.putDoubleArray("lons", lons);
bpars.putString("fast", params.fast ? "1" : "0");
bpars.putString("v", mode);
bpars.putString("trackFormat", "kml");
OsmandApplication ctx = (OsmandApplication) params.ctx;
List<Location> res = new ArrayList<Location>();
BRouterServiceConnection conn = BRouterServiceConnection.connect(ctx);
if (conn == null) {
return new RouteCalculationResult("BRouter service is not available");
}
long begin = System.currentTimeMillis();
try {
while((System.currentTimeMillis() - begin) < 15000 && conn.brouterService == null) {
Thread.sleep(500);
}
if(conn.brouterService == null){
return new RouteCalculationResult("BRouter service is not available");
}
String kmlMessage = conn.brouterService.getTrackFromParams(bpars);
if (kmlMessage == null)
kmlMessage = "no result from brouter";
if (!kmlMessage.startsWith("<")) {
return new RouteCalculationResult(kmlMessage);
}
DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dom.parse(new InputSource(new StringReader(kmlMessage)));
NodeList list = doc.getElementsByTagName("coordinates"); //$NON-NLS-1$
for (int i = 0; i < list.getLength(); i++) {
Node item = list.item(i);
String str = item.getFirstChild().getNodeValue();
if (str == null) {
continue;
}
int st = 0;
int next = 0;
while ((next = str.indexOf('\n', st)) != -1) {
String coordinate = str.substring(st, next + 1);
int s = coordinate.indexOf(',');
if (s != -1) {
try {
double lon = Double.parseDouble(coordinate.substring(0, s));
double lat = Double.parseDouble(coordinate.substring(s + 1));
Location l = new Location("router"); //$NON-NLS-1$
l.setLatitude(lat);
l.setLongitude(lon);
res.add(l);
} catch (NumberFormatException e) {
}
}
st = next + 1;
}
}
if (list.getLength() == 0) {
if (doc.getChildNodes().getLength() == 1) {
Node item = doc.getChildNodes().item(0);
return new RouteCalculationResult(item.getNodeValue());
}
}
conn.disconnect((Context) params.ctx);
} catch (Exception e) {
return new RouteCalculationResult("Exception calling BRouter: " + e); //$NON-NLS-1$
}
return new RouteCalculationResult(res, null, params, null);
}
}

View file

@ -731,7 +731,7 @@ public class RoutingHelper {
msg += " (" + Algorithms.formatDuration((int) res.getRoutingTime()) + ")";
}
showMessage(msg);
} else if (params.type != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) {
} else if (params.type.isOnline() && !settings.isInternetConnectionAvailable()) {
showMessage(app.getString(R.string.error_calculating_route)
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route)); //$NON-NLS-1$
} else {