Add dynamic routing parameters for osmand routing.xml

This commit is contained in:
vshcherb 2014-02-26 20:23:29 +01:00
parent 228c44b395
commit c7e764239b
6 changed files with 218 additions and 47 deletions

View file

@ -101,7 +101,7 @@ public class GeneralRouter implements VehicleRouter {
ruleToValue = new ArrayList<Object>(); ruleToValue = new ArrayList<Object>();
parameters = new LinkedHashMap<String, GeneralRouter.RoutingParameter>(); parameters = new LinkedHashMap<String, GeneralRouter.RoutingParameter>();
} }
public GeneralRouter(GeneralRouter parent, Map<String, String> params) { public GeneralRouter(GeneralRouter parent, Map<String, String> params) {
this.attributes = new LinkedHashMap<String, String>(); this.attributes = new LinkedHashMap<String, String>();
Iterator<Entry<String, String>> e = parent.attributes.entrySet().iterator(); Iterator<Entry<String, String>> e = parent.attributes.entrySet().iterator();
@ -127,6 +127,9 @@ public class GeneralRouter implements VehicleRouter {
} }
public Map<String, RoutingParameter> getParameters() {
return parameters;
}
public void addAttribute(String k, String v) { public void addAttribute(String k, String v) {
attributes.put(k, v); attributes.put(k, v);

View file

@ -98,6 +98,15 @@ public class RoutingConfiguration {
return attributes.get(propertyName); return attributes.get(propertyName);
} }
public String getDefaultRouter() {
return defaultRouter;
}
public GeneralRouter getRouter(String applicationMode) {
return routers.get(applicationMode);
}
} }
private static int parseSilentInt(String t, int v) { private static int parseSilentInt(String t, int v) {
@ -128,7 +137,7 @@ public class RoutingConfiguration {
} }
return DEFAULT; return DEFAULT;
} }
public static RoutingConfiguration.Builder parseFromInputStream(InputStream is) throws IOException, XmlPullParserException { public static RoutingConfiguration.Builder parseFromInputStream(InputStream is) throws IOException, XmlPullParserException {
XmlPullParser parser = PlatformUtil.newXMLPullParser(); XmlPullParser parser = PlatformUtil.newXMLPullParser();
final RoutingConfiguration.Builder config = new RoutingConfiguration.Builder(); final RoutingConfiguration.Builder config = new RoutingConfiguration.Builder();

View file

@ -1394,12 +1394,32 @@ public class OsmandSettings {
Map<String, CommonPreference<Boolean>> customBooleanRendersProps = new LinkedHashMap<String, OsmandSettings.CommonPreference<Boolean>>(); Map<String, CommonPreference<Boolean>> customBooleanRendersProps = new LinkedHashMap<String, OsmandSettings.CommonPreference<Boolean>>();
public CommonPreference<Boolean> getCustomRenderBooleanProperty(String attrName){ public CommonPreference<Boolean> getCustomRenderBooleanProperty(String attrName){
if(!customRendersProps.containsKey(attrName)){ if(!customBooleanRendersProps.containsKey(attrName)){
customBooleanRendersProps.put(attrName, new BooleanPreference("nrenderer_"+attrName, false).makeProfile()); customBooleanRendersProps.put(attrName, new BooleanPreference("nrenderer_"+attrName, false).makeProfile());
} }
return customBooleanRendersProps.get(attrName); return customBooleanRendersProps.get(attrName);
} }
Map<String, CommonPreference<String>> customRoutingProps = new LinkedHashMap<String, OsmandSettings.CommonPreference<String>>();
public CommonPreference<String> getCustomRoutingProperty(String attrName){
if(!customRoutingProps.containsKey(attrName)){
customRoutingProps.put(attrName, new StringPreference("prouting_"+attrName, "").makeProfile());
}
return customRoutingProps.get(attrName);
}
{
// CommonPreference<String> pref = getCustomRoutingProperty("appMode");
// pref.setModeDefaultValue(ApplicationMode.CAR, "car");
}
Map<String, CommonPreference<Boolean>> customBooleanRoutingProps = new LinkedHashMap<String, OsmandSettings.CommonPreference<Boolean>>();
public CommonPreference<Boolean> getCustomRoutingBooleanProperty(String attrName){
if(!customBooleanRoutingProps.containsKey(attrName)){
customBooleanRoutingProps.put(attrName, new BooleanPreference("prouting_"+attrName, false).makeProfile());
}
return customBooleanRoutingProps.get(attrName);
}
public final OsmandPreference<Boolean> VOICE_MUTE = new BooleanPreference("voice_mute", false).makeGlobal(); public final OsmandPreference<Boolean> VOICE_MUTE = new BooleanPreference("voice_mute", false).makeGlobal();
// for background service // for background service

View file

@ -82,6 +82,15 @@ public abstract class SettingsBaseActivity extends SherlockPreferenceActivity im
booleanPreferences.put(b.getId(), b); booleanPreferences.put(b.getId(), b);
return p; return p;
} }
public CheckBoxPreference createCheckBoxPreference(OsmandPreference<Boolean> b) {
CheckBoxPreference p = new CheckBoxPreference(this);
p.setKey(b.getId());
p.setOnPreferenceChangeListener(this);
screenPreferences.put(b.getId(), p);
booleanPreferences.put(b.getId(), b);
return p;
}
public void registerSeekBarPreference(OsmandPreference<Integer> b, PreferenceScreen screen) { public void registerSeekBarPreference(OsmandPreference<Integer> b, PreferenceScreen screen) {
SeekBarPreference p = (SeekBarPreference) screen.findPreference(b.getId()); SeekBarPreference p = (SeekBarPreference) screen.findPreference(b.getId());
@ -89,6 +98,32 @@ public abstract class SettingsBaseActivity extends SherlockPreferenceActivity im
screenPreferences.put(b.getId(), p); screenPreferences.put(b.getId(), p);
seekBarPreferences.put(b.getId(), b); seekBarPreferences.put(b.getId(), b);
} }
public static String getRoutingStringPropertyName(Context ctx, String propertyName, String defValue) {
try {
Field f = R.string.class.getField("routing_attr_" + propertyName + "_name");
if (f != null) {
Integer in = (Integer) f.get(null);
return ctx.getString(in);
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
return defValue;
}
public static String getRoutingStringPropertyDescription(Context ctx, String propertyName, String defValue) {
try {
Field f = R.string.class.getField("routing_attr_" + propertyName + "_description");
if (f != null) {
Integer in = (Integer) f.get(null);
return ctx.getString(in);
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
return defValue;
}
public static String getStringPropertyName(Context ctx, String propertyName, String defValue) { public static String getStringPropertyName(Context ctx, String propertyName, String defValue) {
try { try {
@ -143,6 +178,13 @@ public abstract class SettingsBaseActivity extends SherlockPreferenceActivity im
prepareListPreference(b, names, values, p); prepareListPreference(b, names, values, p);
return p; return p;
} }
public <T> ListPreference createListPreference(OsmandPreference<T> b, String[] names, T[] values) {
ListPreference p = new ListPreference(this);
p.setKey(b.getId());
prepareListPreference(b, names, values, p);
return p;
}
private <T> void prepareListPreference(OsmandPreference<T> b, String[] names, T[] values, ListPreference p) { private <T> void prepareListPreference(OsmandPreference<T> b, String[] names, T[] values, ListPreference p) {
p.setOnPreferenceChangeListener(this); p.setOnPreferenceChangeListener(this);

View file

@ -2,21 +2,30 @@ package net.osmand.plus.activities;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.AutoZoomMap; import net.osmand.plus.OsmandSettings.AutoZoomMap;
import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType;
import net.osmand.router.RoutingConfiguration;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnMultiChoiceClickListener; import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
@ -32,6 +41,9 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
private ListPreference autoZoomMapPreference; private ListPreference autoZoomMapPreference;
public static final String MORE_VALUE = "MORE_VALUE"; public static final String MORE_VALUE = "MORE_VALUE";
private List<RoutingParameter> avoidParameters = new ArrayList<RoutingParameter>();
private List<RoutingParameter> preferParameters = new ArrayList<RoutingParameter>();
public SettingsNavigationActivity() { public SettingsNavigationActivity() {
super(true); super(true);
} }
@ -63,34 +75,28 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
addPreferencesFromResource(R.xml.navigation_settings); addPreferencesFromResource(R.xml.navigation_settings);
PreferenceScreen screen = getPreferenceScreen(); PreferenceScreen screen = getPreferenceScreen();
settings = getMyApplication().getSettings(); settings = getMyApplication().getSettings();
routerServicePreference = (ListPreference) screen.findPreference(settings.ROUTER_SERVICE.getId());
RouteService[] vls = RouteService.getAvailableRouters(getMyApplication());
String[] entries = new String[vls.length];
for(int i=0; i<entries.length; i++){
entries[i] = vls[i].getName();
}
registerListPreference(settings.ROUTER_SERVICE, screen, entries, vls);
registerBooleanPreference(settings.FAST_ROUTE_MODE, screen);
PreferenceCategory cat = (PreferenceCategory) screen.findPreference("routing_preferences");
avoidRouting = (Preference) screen.findPreference("avoid_in_routing");
avoidRouting.setOnPreferenceClickListener(this);
// routing_preferences
preferRouting = (Preference) screen.findPreference("prefer_in_routing");
preferRouting.setOnPreferenceClickListener(this);
registerBooleanPreference(settings.SNAP_TO_ROAD, screen); registerBooleanPreference(settings.SNAP_TO_ROAD, screen);
registerBooleanPreference(settings.USE_COMPASS_IN_NAVIGATION, screen); registerBooleanPreference(settings.USE_COMPASS_IN_NAVIGATION, screen);
Integer[] intValues = new Integer[] { 0, 5, 10, 15, 20, 25, 30, 45, 60, 90}; Integer[] intValues = new Integer[] { 0, 5, 10, 15, 20, 25, 30, 45, 60, 90};
String[] entries = new String[intValues.length]; entries = new String[intValues.length];
entries[0] = getString(R.string.auto_follow_route_never); entries[0] = getString(R.string.auto_follow_route_never);
for (int i = 1; i < intValues.length; i++) { for (int i = 1; i < intValues.length; i++) {
entries[i] = (int) intValues[i] + " " + getString(R.string.int_seconds); entries[i] = (int) intValues[i] + " " + getString(R.string.int_seconds);
} }
registerListPreference(settings.AUTO_FOLLOW_ROUTE, screen, entries, intValues); registerListPreference(settings.AUTO_FOLLOW_ROUTE, screen, entries, intValues);
RouteService[] vls = RouteService.getAvailableRouters(getMyApplication());
entries = new String[vls.length];
for(int i=0; i<entries.length; i++){
entries[i] = vls[i].getName();
}
registerListPreference(settings.ROUTER_SERVICE, screen, entries, vls);
routerServicePreference = (ListPreference) screen.findPreference(settings.ROUTER_SERVICE.getId());
entries = new String[AutoZoomMap.values().length]; entries = new String[AutoZoomMap.values().length];
for(int i=0; i<entries.length; i++){ for(int i=0; i<entries.length; i++){
@ -108,10 +114,88 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
speakAlarms = (Preference) screen.findPreference("speak_routing_alarms"); speakAlarms = (Preference) screen.findPreference("speak_routing_alarms");
speakAlarms.setOnPreferenceClickListener(this); speakAlarms.setOnPreferenceClickListener(this);
reloadVoiceListPreference(screen);
profileDialog(); profileDialog();
} }
private void prepareRoutingPrefs(PreferenceScreen screen) {
PreferenceCategory cat = (PreferenceCategory) screen.findPreference("routing_preferences");
cat.removeAll();
CheckBoxPreference fastRoute = createCheckBoxPreference(settings.FAST_ROUTE_MODE, R.string.fast_route_mode, R.string.fast_route_mode_descr);
if(settings.ROUTER_SERVICE.get() != RouteService.OSMAND) {
cat.addPreference(fastRoute);
} else {
ApplicationMode am = settings.getApplicationMode();
GeneralRouter router = getRouter(am);
clearParameters();
if (router != null) {
Map<String, RoutingParameter> parameters = router.getParameters();
if(parameters.containsKey("short_way")) {
cat.addPreference(fastRoute);
}
List<RoutingParameter> others = new ArrayList<GeneralRouter.RoutingParameter>();
for(Map.Entry<String, RoutingParameter> e : parameters.entrySet()) {
String param = e.getKey();
if(param.startsWith("avoid_")) {
avoidParameters.add(e.getValue());
} else if(param.startsWith("prefer_")) {
preferParameters.add(e.getValue());
} else if(!param.equals("short_way")) {
others.add(e.getValue());
}
}
if (avoidParameters.size() > 0) {
avoidRouting = new Preference(this);
avoidRouting.setTitle(R.string.avoid_in_routing_title);
avoidRouting.setSummary(R.string.avoid_in_routing_descr);
avoidRouting.setOnPreferenceClickListener(this);
cat.addPreference(avoidRouting);
}
if (preferParameters.size() > 0) {
preferRouting = new Preference(this);
preferRouting.setTitle(R.string.prefer_in_routing_title);
preferRouting.setSummary(R.string.prefer_in_routing_descr);
preferRouting.setOnPreferenceClickListener(this);
cat.addPreference(preferRouting);
}
for(RoutingParameter p : others) {
Preference basePref;
if(p.getType() == RoutingParameterType.BOOLEAN) {
basePref = createCheckBoxPreference(settings.getCustomRoutingBooleanProperty(p.getId()));
} else {
Object[] vls = p.getPossibleValues();
String[] svlss = new String[vls.length];
int i = 0;
for(Object o : vls) {
svlss[i++] = o.toString();
}
basePref = createListPreference(settings.getCustomRoutingProperty(p.getId()),
p.getPossibleValueDescriptions(), svlss);
}
basePref.setTitle(SettingsBaseActivity.getRoutingStringPropertyName(this, p.getId(), p.getName()));
basePref.setSummary(SettingsBaseActivity.getRoutingStringPropertyName(this, p.getId(), p.getDescription()));
cat.addPreference(basePref);
}
}
}
}
private void clearParameters() {
preferParameters.clear();
avoidParameters.clear();
}
public static GeneralRouter getRouter(ApplicationMode am) {
GeneralRouter router = RoutingConfiguration.getDefault().getRouter(am.getStringKey());
if(router == null && am.getParent() != null) {
router = RoutingConfiguration.getDefault().getRouter(am.getParent().getStringKey());
}
return router;
}
private void reloadVoiceListPreference(PreferenceScreen screen) { private void reloadVoiceListPreference(PreferenceScreen screen) {
@ -137,6 +221,7 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
public void updateAllSettings() { public void updateAllSettings() {
reloadVoiceListPreference(getPreferenceScreen()); reloadVoiceListPreference(getPreferenceScreen());
prepareRoutingPrefs(getPreferenceScreen());
super.updateAllSettings(); super.updateAllSettings();
routerServicePreference.setSummary(getString(R.string.router_service_descr) + " [" + settings.ROUTER_SERVICE.get() + "]"); routerServicePreference.setSummary(getString(R.string.router_service_descr) + " [" + settings.ROUTER_SERVICE.get() + "]");
} }
@ -156,11 +241,11 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
} }
return true; return true;
} }
boolean changed = super.onPreferenceChange(preference, newValue); super.onPreferenceChange(preference, newValue);
if (id.equals(settings.ROUTER_SERVICE.getId())) { if (id.equals(settings.ROUTER_SERVICE.getId())) {
routerServicePreference.setSummary(getString(R.string.router_service_descr) + " [" routerServicePreference.setSummary(getString(R.string.router_service_descr) + " ["
+ settings.ROUTER_SERVICE.get() + "]"); + settings.ROUTER_SERVICE.get() + "]");
prepareRoutingPrefs(getPreferenceScreen());
} }
return true; return true;
} }
@ -169,15 +254,16 @@ public class SettingsNavigationActivity extends SettingsBaseActivity {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
if (preference == avoidRouting) { if (preference == avoidRouting || preference == preferRouting) {
showBooleanSettings(new String[] { getString(R.string.avoid_toll_roads), getString(R.string.avoid_ferries), List<RoutingParameter> prms = preference == avoidRouting ? avoidParameters : preferParameters;
getString(R.string.avoid_unpaved), getString(R.string.avoid_motorway) String[] vals = new String[prms.size()];
}, new OsmandPreference[] { settings.AVOID_TOLL_ROADS, OsmandPreference[] bls = new OsmandPreference[prms.size()];
settings.AVOID_FERRIES, settings.AVOID_UNPAVED_ROADS, settings.AVOID_MOTORWAY }); for(int i = 0; i < prms.size(); i++) {
return true; RoutingParameter p = prms.get(i);
} else if (preference == preferRouting) { vals[i] = SettingsBaseActivity.getRoutingStringPropertyName(this, p.getId(), p.getName());
showBooleanSettings(new String[] { getString(R.string.prefer_motorways)}, bls[i] = settings.getCustomRoutingBooleanProperty(p.getId());
new OsmandPreference[] { settings.PREFER_MOTORWAYS}); }
showBooleanSettings(vals, bls);
return true; return true;
} else if (preference == showAlarms) { } else if (preference == showAlarms) {
showBooleanSettings(new String[] { getString(R.string.show_traffic_warnings), getString(R.string.show_cameras), showBooleanSettings(new String[] { getString(R.string.show_traffic_warnings), getString(R.string.show_cameras),

View file

@ -39,11 +39,15 @@ import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType;
import net.osmand.router.RoutePlannerFrontEnd; import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode; import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
@ -391,23 +395,28 @@ public class RouteProvider {
} else { } else {
return applicationModeNotSupported(params); return applicationModeNotSupported(params);
} }
GeneralRouter generalRouter = SettingsNavigationActivity.getRouter(params.mode);
if(generalRouter == null) {
return applicationModeNotSupported(params);
}
Map<String, String> paramsR = new LinkedHashMap<String, String>(); Map<String, String> paramsR = new LinkedHashMap<String, String>();
if (!settings.FAST_ROUTE_MODE.getModeValue(params.mode)) { for(Map.Entry<String, RoutingParameter> e : generalRouter.getParameters().entrySet()){
paramsR.put(GeneralRouter.USE_SHORTEST_WAY, "true"); String key = e.getKey();
} RoutingParameter pr = e.getValue();
if(settings.AVOID_FERRIES.getModeValue(params.mode)){ String vl;
paramsR.put(GeneralRouter.AVOID_FERRIES, "true"); if(key.equals(GeneralRouter.USE_SHORTEST_WAY)) {
} Boolean bool = settings.FAST_ROUTE_MODE.getModeValue(params.mode);
if(settings.AVOID_TOLL_ROADS.getModeValue(params.mode)){ vl = bool ? "true" : null;
paramsR.put(GeneralRouter.AVOID_TOLL, "true"); } else if(pr.getType() == RoutingParameterType.BOOLEAN) {
} CommonPreference<Boolean> pref = settings.getCustomRoutingBooleanProperty(key);
if(settings.AVOID_MOTORWAY.getModeValue(params.mode)){ Boolean bool = pref.getModeValue(params.mode);
paramsR.put(GeneralRouter.AVOID_MOTORWAY, "true"); vl = bool ? "true" : null;
} else if(settings.PREFER_MOTORWAYS.getModeValue(params.mode)){ } else {
paramsR.put(GeneralRouter.PREFER_MOTORWAYS, "true"); vl = settings.getCustomRoutingProperty(key).getModeValue(params.mode);
} }
if(settings.AVOID_UNPAVED_ROADS.getModeValue(params.mode)){ if(vl != null && vl.length() > 0) {
paramsR.put(GeneralRouter.AVOID_UNPAVED, "true"); paramsR.put(key, vl);
}
} }
float mb = (1 << 20); float mb = (1 << 20);
Runtime rt = Runtime.getRuntime(); Runtime rt = Runtime.getRuntime();
@ -957,4 +966,6 @@ public class RouteProvider {
return new RouteCalculationResult(res, null, params, null); return new RouteCalculationResult(res, null, params, null);
} }
} }