Add new routing config

This commit is contained in:
vshcherb 2014-02-05 17:57:24 +01:00
parent db06f5ee00
commit 7e9053b2bc
4 changed files with 91 additions and 52 deletions

View file

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

View file

@ -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,18 +309,21 @@ 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;
} }
} }
} }
if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
double rt = getRoundaboutTurn(); double rt = getRoundaboutTurn();
if(rt > 0 && !prev.getRoad().roundabout() && segment.getRoad().roundabout()) { if(rt > 0) {
return rt; 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);
double a2 = prev.getRoad().directionRoute(prevSegmentEnd, prevSegmentEnd < prev.getSegmentStart()); double a2 = prev.getRoad().directionRoute(prevSegmentEnd, prevSegmentEnd < prev.getSegmentStart());
@ -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 {
@ -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);
}
}
} }

View file

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

View file

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