Add new routing config
This commit is contained in:
parent
db06f5ee00
commit
7e9053b2bc
4 changed files with 91 additions and 52 deletions
|
@ -1,32 +1,23 @@
|
||||||
package net.osmand;
|
package net.osmand;
|
||||||
|
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.render.RenderingRuleSearchRequest;
|
import net.osmand.render.RenderingRuleSearchRequest;
|
||||||
import net.osmand.render.RenderingRulesStorage;
|
import net.osmand.render.RenderingRulesStorage;
|
||||||
import net.osmand.router.GeneralRouter;
|
|
||||||
import net.osmand.router.PrecalculatedRouteDirection;
|
import net.osmand.router.PrecalculatedRouteDirection;
|
||||||
import net.osmand.router.RouteCalculationProgress;
|
import net.osmand.router.RouteCalculationProgress;
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
import net.osmand.router.RoutingConfiguration;
|
import net.osmand.router.RoutingConfiguration;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
public class NativeLibrary {
|
public class NativeLibrary {
|
||||||
|
|
||||||
protected final boolean newLibrary;
|
protected final boolean newLibrary;
|
||||||
|
@ -132,34 +123,11 @@ public class NativeLibrary {
|
||||||
public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config,
|
public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config,
|
||||||
RouteRegion[] regions, RouteCalculationProgress progress, PrecalculatedRouteDirection precalculatedRouteDirection,
|
RouteRegion[] regions, RouteCalculationProgress progress, PrecalculatedRouteDirection precalculatedRouteDirection,
|
||||||
boolean basemap) {
|
boolean basemap) {
|
||||||
TIntArrayList state = new TIntArrayList();
|
// config.router.printRules(System.out);
|
||||||
List<String> keys = new ArrayList<String>();
|
return nativeRouting(new int[] { sx31, sy31, ex31, ey31 }, config, config.initialDirection == null ? -360 : config.initialDirection.floatValue(),
|
||||||
List<String> values = new ArrayList<String>();
|
|
||||||
GeneralRouter r = (GeneralRouter) config.router;
|
|
||||||
// TODO
|
|
||||||
// fillObjects(state, keys, values, 0, r.highwaySpeed);
|
|
||||||
// fillObjects(state, keys, values, 1, r.highwayPriorities);
|
|
||||||
// fillObjects(state, keys, values, 2, r.avoid);
|
|
||||||
// fillObjects(state, keys, values, 3, r.obstacles);
|
|
||||||
// fillObjects(state, keys, values, 4, r.routingObstacles);
|
|
||||||
LinkedHashMap<String, String> attrs = new LinkedHashMap<String, String>(config.attributes);
|
|
||||||
attrs.putAll(r.attributes);
|
|
||||||
fillObjects(state, keys, values, 5, attrs);
|
|
||||||
|
|
||||||
return nativeRouting(new int[] { sx31, sy31, ex31, ey31 }, state.toArray(), keys.toArray(new String[keys.size()]),
|
|
||||||
values.toArray(new String[values.size()]), config.initialDirection == null ? -360 : config.initialDirection.floatValue(),
|
|
||||||
regions, progress, precalculatedRouteDirection, basemap);
|
regions, progress, precalculatedRouteDirection, basemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void fillObjects(TIntArrayList state, List<String> keys, List<String> values, int s, Map<String, T> map) {
|
|
||||||
Iterator<Entry<String, T>> it = map.entrySet().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<String, T> n = it.next();
|
|
||||||
state.add(s);
|
|
||||||
keys.add(n.getKey());
|
|
||||||
values.add(n.getValue() + "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
|
public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
|
||||||
NativeRouteSearchResult lr = loadRoutingData(sub.routeReg, sub.routeReg.getName(), sub.routeReg.getFilePointer(), sub, loadObjects);
|
NativeRouteSearchResult lr = loadRoutingData(sub.routeReg, sub.routeReg.getName(), sub.routeReg.getFilePointer(), sub, loadObjects);
|
||||||
|
@ -177,7 +145,7 @@ public class NativeLibrary {
|
||||||
|
|
||||||
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
|
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
|
||||||
|
|
||||||
protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig,
|
protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, RoutingConfiguration r,
|
||||||
float initDirection, RouteRegion[] regions, RouteCalculationProgress progress, PrecalculatedRouteDirection precalculatedRouteDirection, boolean basemap);
|
float initDirection, RouteRegion[] regions, RouteCalculationProgress progress, PrecalculatedRouteDirection precalculatedRouteDirection, boolean basemap);
|
||||||
|
|
||||||
protected static native void deleteSearchResult(long searchResultHandle);
|
protected static native void deleteSearchResult(long searchResultHandle);
|
||||||
|
|
|
@ -236,7 +236,7 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VehicleRouter build(Map<String, String> params) {
|
public GeneralRouter build(Map<String, String> params) {
|
||||||
return new GeneralRouter(this, params);
|
return new GeneralRouter(this, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,17 +309,20 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
int[] pt = prev.getRoad().getPointTypes(prevSegmentEnd);
|
int[] pt = prev.getRoad().getPointTypes(prevSegmentEnd);
|
||||||
if(pt != null) {
|
if(pt != null) {
|
||||||
RouteRegion reg = prev.getRoad().region;
|
RouteRegion reg = prev.getRoad().region;
|
||||||
for(int i=0; i<pt.length; i++) {
|
for (int i = 0; i < pt.length; i++) {
|
||||||
RouteTypeRule r = reg.quickGetEncodingRule(pt[i]);
|
RouteTypeRule r = reg.quickGetEncodingRule(pt[i]);
|
||||||
if("highway".equals(r.getTag()) && "traffic_signals".equals(r.getValue())) {
|
if ("highway".equals(r.getTag()) && "traffic_signals".equals(r.getValue())) {
|
||||||
// traffic signals don't add turn info
|
// traffic signals don't add turn info
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double rt = getRoundaboutTurn();
|
|
||||||
if(rt > 0 && !prev.getRoad().roundabout() && segment.getRoad().roundabout()) {
|
if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
|
||||||
return rt;
|
double rt = getRoundaboutTurn();
|
||||||
|
if(rt > 0) {
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (getLeftTurn() > 0 || getRightTurn() > 0) {
|
if (getLeftTurn() > 0 || getRightTurn() > 0) {
|
||||||
double a1 = segment.getRoad().directionRoute(segment.getSegmentStart(), segment.getSegmentStart() < segmentEnd);
|
double a1 = segment.getRoad().directionRoute(segment.getSegmentStart(), segment.getSegmentStart() < segmentEnd);
|
||||||
|
@ -416,6 +419,24 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RouteAttributeEvalRule[] getRules() {
|
||||||
|
return rules.toArray(new RouteAttributeEvalRule[rules.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getParamKeys() {
|
||||||
|
if(paramContext == null) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return paramContext.vars.keySet().toArray(new String[paramContext.vars.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getParamValues() {
|
||||||
|
if(paramContext == null) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
return paramContext.vars.values().toArray(new String[paramContext.vars.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
private Object evaluate(RouteDataObject ro) {
|
private Object evaluate(RouteDataObject ro) {
|
||||||
return evaluate(convert(ro.region, ro.types));
|
return evaluate(convert(ro.region, ro.types));
|
||||||
}
|
}
|
||||||
|
@ -540,10 +561,11 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// definition
|
||||||
private String[] values;
|
private String[] values;
|
||||||
private int expressionType;
|
private int expressionType;
|
||||||
private String valueType;
|
private String valueType;
|
||||||
|
// numbers
|
||||||
private Number[] cacheValues;
|
private Number[] cacheValues;
|
||||||
|
|
||||||
public boolean matches(BitSet types, ParameterContext paramContext) {
|
public boolean matches(BitSet types, ParameterContext paramContext) {
|
||||||
|
@ -579,7 +601,7 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
} else if (value instanceof String && value.toString().startsWith(":")) {
|
} else if (value instanceof String && value.toString().startsWith(":")) {
|
||||||
String p = ((String) value).substring(1);
|
String p = ((String) value).substring(1);
|
||||||
if (paramContext != null && paramContext.vars.containsKey(p)) {
|
if (paramContext != null && paramContext.vars.containsKey(p)) {
|
||||||
o = parseValue(paramContext.vars.get(p), value);
|
o = parseValue(paramContext.vars.get(p), valueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,6 +616,11 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
|
|
||||||
public class RouteAttributeEvalRule {
|
public class RouteAttributeEvalRule {
|
||||||
protected List<String> parameters = new ArrayList<String>() ;
|
protected List<String> parameters = new ArrayList<String>() ;
|
||||||
|
protected List<String> tagValueCondDefTag = new ArrayList<String>();
|
||||||
|
protected List<String> tagValueCondDefValue = new ArrayList<String>();
|
||||||
|
protected List<Boolean> tagValueCondDefNot = new ArrayList<Boolean>();
|
||||||
|
|
||||||
|
protected String selectValueDef = null;
|
||||||
protected Object selectValue = null;
|
protected Object selectValue = null;
|
||||||
protected String selectType = null;
|
protected String selectType = null;
|
||||||
protected BitSet filterTypes = new BitSet();
|
protected BitSet filterTypes = new BitSet();
|
||||||
|
@ -604,7 +631,34 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
protected Set<String> onlyNotTags = new LinkedHashSet<String>();
|
protected Set<String> onlyNotTags = new LinkedHashSet<String>();
|
||||||
protected List<RouteAttributeExpression> expressions = new ArrayList<RouteAttributeExpression>();
|
protected List<RouteAttributeExpression> expressions = new ArrayList<RouteAttributeExpression>();
|
||||||
|
|
||||||
|
|
||||||
|
public RouteAttributeExpression[] getExpressions() {
|
||||||
|
return expressions.toArray(new RouteAttributeExpression[expressions.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getParameters() {
|
||||||
|
return parameters.toArray(new String[parameters.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getTagValueCondDefTag() {
|
||||||
|
return tagValueCondDefTag.toArray(new String[tagValueCondDefTag.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getTagValueCondDefValue() {
|
||||||
|
return tagValueCondDefValue.toArray(new String[tagValueCondDefValue.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] getTagValueCondDefNot() {
|
||||||
|
boolean[] r = new boolean[tagValueCondDefNot.size()];
|
||||||
|
for (int i = 0; i < r.length; i++) {
|
||||||
|
r[i] = tagValueCondDefNot.get(i).booleanValue();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
public void registerSelectValue(String value, String type) {
|
public void registerSelectValue(String value, String type) {
|
||||||
|
selectType = type;
|
||||||
|
selectValueDef = value;
|
||||||
if(value.startsWith(":") || value.startsWith("$")) {
|
if(value.startsWith(":") || value.startsWith("$")) {
|
||||||
selectValue = value;
|
selectValue = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -616,7 +670,7 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printRule(PrintStream out) {
|
public void printRule(PrintStream out) {
|
||||||
out.print(" Select " + selectValue + " if ");
|
out.print(" Select " + selectValue + " if ");
|
||||||
for(int k = 0; k < filterTypes.size(); k++) {
|
for(int k = 0; k < filterTypes.size(); k++) {
|
||||||
if(filterTypes.get(k)) {
|
if(filterTypes.get(k)) {
|
||||||
String key = universalRulesById.get(k);
|
String key = universalRulesById.get(k);
|
||||||
|
@ -641,10 +695,16 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
if(onlyNotTags.size() > 0) {
|
if(onlyNotTags.size() > 0) {
|
||||||
out.print(" not match tag = " + onlyNotTags);
|
out.print(" not match tag = " + onlyNotTags);
|
||||||
}
|
}
|
||||||
|
if(expressions.size() > 0) {
|
||||||
|
out.println(" subexpressions " + expressions.size());
|
||||||
|
}
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerAndTagValueCondition(String tag, String value, boolean not) {
|
public void registerAndTagValueCondition(String tag, String value, boolean not) {
|
||||||
|
tagValueCondDefTag.add(tag);
|
||||||
|
tagValueCondDefValue.add(value);
|
||||||
|
tagValueCondDefNot.add(not);
|
||||||
if(value == null) {
|
if(value == null) {
|
||||||
if (not) {
|
if (not) {
|
||||||
onlyNotTags.add(tag);
|
onlyNotTags.add(tag);
|
||||||
|
@ -763,6 +823,7 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
private boolean checkAllTypesShouldBePresent(BitSet types) {
|
private boolean checkAllTypesShouldBePresent(BitSet types) {
|
||||||
// Bitset method subset is missing "filterTypes.isSubset(types)"
|
// Bitset method subset is missing "filterTypes.isSubset(types)"
|
||||||
// reset previous evaluation
|
// reset previous evaluation
|
||||||
|
// evalFilterTypes.clear(); // not needed same as or()
|
||||||
evalFilterTypes.or(filterTypes);
|
evalFilterTypes.or(filterTypes);
|
||||||
// evaluate bit intersection and check if filterTypes contained as set in types
|
// evaluate bit intersection and check if filterTypes contained as set in types
|
||||||
evalFilterTypes.and(types);
|
evalFilterTypes.and(types);
|
||||||
|
@ -773,5 +834,14 @@ public class GeneralRouter implements VehicleRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printRules(PrintStream out) {
|
||||||
|
for(int i = 0; i < RouteDataObjectAttribute.values().length ; i++) {
|
||||||
|
out.println(RouteDataObjectAttribute.values()[i]);
|
||||||
|
objectAttributes[i].printRules(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ public class RoutingConfiguration {
|
||||||
public int planRoadDirection = 0;
|
public int planRoadDirection = 0;
|
||||||
|
|
||||||
// 1.3 Router specific coefficients and restrictions
|
// 1.3 Router specific coefficients and restrictions
|
||||||
public VehicleRouter router = new GeneralRouter(GeneralRouterProfile.CAR, new LinkedHashMap<String, String>());
|
// use GeneralRouter and not interface to simplify native access !
|
||||||
|
public GeneralRouter router = new GeneralRouter(GeneralRouterProfile.CAR, new LinkedHashMap<String, String>());
|
||||||
public String routerName = "";
|
public String routerName = "";
|
||||||
|
|
||||||
// 1.4 Used to calculate route in movement
|
// 1.4 Used to calculate route in movement
|
||||||
|
@ -48,7 +49,7 @@ public class RoutingConfiguration {
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
// Design time storage
|
// Design time storage
|
||||||
private String defaultRouter = "";
|
private String defaultRouter = "";
|
||||||
private Map<String, VehicleRouter> routers = new LinkedHashMap<String, VehicleRouter>();
|
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
|
||||||
private Map<String, String> attributes = new LinkedHashMap<String, String>();
|
private Map<String, String> attributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
public RoutingConfiguration build(String router, int memoryLimitMB) {
|
public RoutingConfiguration build(String router, int memoryLimitMB) {
|
||||||
|
@ -233,7 +234,7 @@ public class RoutingConfiguration {
|
||||||
|
|
||||||
private static boolean checkTag(String pname) {
|
private static boolean checkTag(String pname) {
|
||||||
return "select".equals(pname) || "if".equals(pname) || "ifnot".equals(pname)
|
return "select".equals(pname) || "if".equals(pname) || "ifnot".equals(pname)
|
||||||
|| "ge".equals(pname) || "le".equals(pname);
|
|| "gt".equals(pname) || "le".equals(pname);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addSubclause(RoutingRule rr, RouteAttributeContext ctx) {
|
private static void addSubclause(RoutingRule rr, RouteAttributeContext ctx) {
|
||||||
|
@ -244,7 +245,7 @@ public class RoutingConfiguration {
|
||||||
if (!Algorithms.isEmpty(rr.t)) {
|
if (!Algorithms.isEmpty(rr.t)) {
|
||||||
ctx.getLastRule().registerAndTagValueCondition(rr.t, Algorithms.isEmpty(rr.v) ? null : rr.v, not);
|
ctx.getLastRule().registerAndTagValueCondition(rr.t, Algorithms.isEmpty(rr.v) ? null : rr.v, not);
|
||||||
}
|
}
|
||||||
if (rr.tagName.equals("ge")) {
|
if (rr.tagName.equals("gt")) {
|
||||||
ctx.getLastRule().registerGreatCondition(rr.value1, rr.value2, rr.type);
|
ctx.getLastRule().registerGreatCondition(rr.value1, rr.value2, rr.type);
|
||||||
} else if (rr.tagName.equals("le")) {
|
} else if (rr.tagName.equals("le")) {
|
||||||
ctx.getLastRule().registerLessCondition(rr.value1, rr.value2, rr.type);
|
ctx.getLastRule().registerLessCondition(rr.value1, rr.value2, rr.type);
|
||||||
|
|
|
@ -184,7 +184,7 @@ public class RoutingContext {
|
||||||
this.visitor = visitor;
|
this.visitor = visitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRouter(VehicleRouter router) {
|
public void setRouter(GeneralRouter router) {
|
||||||
config.router = router;
|
config.router = router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue