Update native routing
This commit is contained in:
parent
efaf4e25c4
commit
0a2edd2afc
10 changed files with 428 additions and 314 deletions
|
@ -1,13 +1,23 @@
|
|||
package net.osmand;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
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 net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.render.RenderingRuleSearchRequest;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.router.GeneralRouter;
|
||||
import net.osmand.router.RouteSegmentResult;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
|
||||
public class NativeLibrary {
|
||||
|
||||
|
@ -99,8 +109,32 @@ public class NativeLibrary {
|
|||
return closeBinaryMapFile(filePath);
|
||||
}
|
||||
|
||||
public RouteSegmentResult[] testRoutingInternal(int sx31, int sy31, int ex31, int ey31) {
|
||||
return testRouting(sx31, sy31, ex31, ey31);
|
||||
public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config) {
|
||||
TIntArrayList state = new TIntArrayList();
|
||||
List<String> keys = new ArrayList<String>();
|
||||
List<String> values = new ArrayList<String>();
|
||||
GeneralRouter r = (GeneralRouter) config.router;
|
||||
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()]));
|
||||
}
|
||||
|
||||
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()+"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,7 +156,7 @@ public class NativeLibrary {
|
|||
|
||||
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
|
||||
|
||||
protected static native RouteSegmentResult[] testRouting(int sx31, int sy31, int ex31, int ey31);
|
||||
protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig);
|
||||
|
||||
protected static native void deleteSearchResult(long searchResultHandle);
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
|
@ -17,26 +19,25 @@ public class GeneralRouter extends VehicleRouter {
|
|||
public static final String AVOID_MOTORWAY = "avoid_motorway";
|
||||
public static final String AVOID_UNPAVED = "avoid_unpaved";
|
||||
|
||||
Map<String, Float> highwaySpeed ;
|
||||
Map<String, Float> highwayPriorities ;
|
||||
Map<String, Float> highwayFuturePriorities ;
|
||||
Map<String, Float> avoid ;
|
||||
Map<String, Float> obstacles;
|
||||
Map<String, Float> routingObstacles;
|
||||
Map<String, String> attributes;
|
||||
public Map<String, Float> highwaySpeed ;
|
||||
public Map<String, Float> highwayPriorities ;
|
||||
public Map<String, Float> avoid ;
|
||||
public Map<String, Float> obstacles;
|
||||
public Map<String, Float> routingObstacles;
|
||||
public Map<String, String> attributes;
|
||||
|
||||
|
||||
private GeneralRouterProfile profile;
|
||||
|
||||
// cached values
|
||||
private Boolean restrictionsAware;
|
||||
private Float leftTurn;
|
||||
private Float roundaboutTurn;
|
||||
private Float rightTurn;
|
||||
private Boolean onewayAware;
|
||||
private Boolean followSpeedLimitations;
|
||||
private Float minDefaultSpeed;
|
||||
private Float maxDefaultSpeed;
|
||||
private boolean restrictionsAware = true;
|
||||
private float leftTurn;
|
||||
private float roundaboutTurn;
|
||||
private float rightTurn;
|
||||
private boolean onewayAware = true;
|
||||
private boolean followSpeedLimitations = true;
|
||||
private float minDefaultSpeed = 10;
|
||||
private float maxDefaultSpeed = 10;
|
||||
|
||||
public enum GeneralRouterProfile {
|
||||
CAR,
|
||||
|
@ -49,21 +50,51 @@ public class GeneralRouter extends VehicleRouter {
|
|||
this.profile = profile;
|
||||
highwaySpeed = new LinkedHashMap<String, Float>();
|
||||
highwayPriorities = new LinkedHashMap<String, Float>();
|
||||
highwayFuturePriorities = new LinkedHashMap<String, Float>();
|
||||
avoid = new LinkedHashMap<String, Float>();
|
||||
obstacles = new LinkedHashMap<String, Float>();
|
||||
routingObstacles = new LinkedHashMap<String, Float>();
|
||||
Iterator<Entry<String, String>> e = attributes.entrySet().iterator();
|
||||
while(e.hasNext()){
|
||||
Entry<String, String> next = e.next();
|
||||
addAttribute(next.getKey(), next.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public GeneralRouter(GeneralRouter pr) {
|
||||
this.highwaySpeed = new LinkedHashMap<String, Float>(pr.highwaySpeed);
|
||||
this.highwayPriorities = new LinkedHashMap<String, Float>(pr.highwayPriorities);
|
||||
this.highwayFuturePriorities = new LinkedHashMap<String, Float>(pr.highwayFuturePriorities);
|
||||
this.avoid = new LinkedHashMap<String, Float>(pr.avoid);
|
||||
this.obstacles = new LinkedHashMap<String, Float>(pr.obstacles);
|
||||
this.routingObstacles = new LinkedHashMap<String, Float>(pr.routingObstacles);
|
||||
this.attributes = new LinkedHashMap<String, String>(pr.attributes);
|
||||
this.profile = pr.profile;
|
||||
Iterator<Entry<String, String>> e = pr.attributes.entrySet().iterator();
|
||||
while(e.hasNext()){
|
||||
Entry<String, String> next = e.next();
|
||||
addAttribute(next.getKey(), next.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addAttribute(String k, String v) {
|
||||
attributes.put(k, v);
|
||||
if(k.equals("restrictionsAware")) {
|
||||
restrictionsAware = parseSilentBoolean(v, restrictionsAware);
|
||||
} else if(k.equals("onewayAware")) {
|
||||
onewayAware = parseSilentBoolean(v, onewayAware);
|
||||
} else if(k.equals("followSpeedLimitations")) {
|
||||
followSpeedLimitations = parseSilentBoolean(v, followSpeedLimitations);
|
||||
} else if(k.equals("leftTurn")) {
|
||||
leftTurn = parseSilentFloat(v, leftTurn);
|
||||
} else if(k.equals("rightTurn")) {
|
||||
rightTurn = parseSilentFloat(v, rightTurn);
|
||||
} else if(k.equals("roundaboutTurn")) {
|
||||
roundaboutTurn = parseSilentFloat(v, roundaboutTurn);
|
||||
} else if(k.equals("minDefaultSpeed")) {
|
||||
minDefaultSpeed = parseSilentFloat(v, minDefaultSpeed * 3.6f) / 3.6f;
|
||||
} else if(k.equals("maxDefaultSpeed")) {
|
||||
maxDefaultSpeed = parseSilentFloat(v, maxDefaultSpeed * 3.6f) / 3.6f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,9 +136,6 @@ public class GeneralRouter extends VehicleRouter {
|
|||
|
||||
@Override
|
||||
public boolean restrictionsAware() {
|
||||
if(restrictionsAware == null) {
|
||||
restrictionsAware = parseSilentBoolean(attributes.get("restrictionsAware"), true);
|
||||
}
|
||||
return restrictionsAware;
|
||||
}
|
||||
|
||||
|
@ -156,9 +184,6 @@ public class GeneralRouter extends VehicleRouter {
|
|||
}
|
||||
|
||||
public boolean isOnewayAware() {
|
||||
if(onewayAware == null) {
|
||||
onewayAware = parseSilentBoolean(attributes.get("onewayAware"), true);
|
||||
}
|
||||
return onewayAware;
|
||||
}
|
||||
|
||||
|
@ -170,23 +195,9 @@ public class GeneralRouter extends VehicleRouter {
|
|||
return super.isOneWay(road);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFutureRoadPriority(RouteDataObject road) {
|
||||
float priority = 1;
|
||||
for (int i = 0; i < road.types.length; i++) {
|
||||
RouteTypeRule r = road.region.quickGetEncodingRule(road.types[i]);
|
||||
if(highwayFuturePriorities.containsKey(r.getTag()+"$"+r.getValue())){
|
||||
priority = highwayFuturePriorities.get(r.getTag()+"$"+r.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFollowSpeedLimitations(){
|
||||
if(followSpeedLimitations == null){
|
||||
followSpeedLimitations = parseSilentBoolean(attributes.get("followSpeedLimitations"), true);
|
||||
}
|
||||
return followSpeedLimitations;
|
||||
}
|
||||
|
||||
|
@ -241,38 +252,23 @@ public class GeneralRouter extends VehicleRouter {
|
|||
|
||||
@Override
|
||||
public float getMinDefaultSpeed() {
|
||||
if(minDefaultSpeed == null ){
|
||||
minDefaultSpeed = parseSilentFloat(attributes.get("minDefaultSpeed"), 10);
|
||||
}
|
||||
return minDefaultSpeed / 3.6f;
|
||||
return minDefaultSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxDefaultSpeed() {
|
||||
if(maxDefaultSpeed == null ){
|
||||
maxDefaultSpeed = parseSilentFloat(attributes.get("maxDefaultSpeed"), 10);
|
||||
}
|
||||
return maxDefaultSpeed / 3.6f;
|
||||
return maxDefaultSpeed ;
|
||||
}
|
||||
|
||||
|
||||
public double getLeftTurn() {
|
||||
if(leftTurn == null) {
|
||||
leftTurn = parseSilentFloat(attributes.get("leftTurn"), 0);
|
||||
}
|
||||
return leftTurn;
|
||||
}
|
||||
|
||||
public double getRightTurn() {
|
||||
if(rightTurn == null) {
|
||||
rightTurn = parseSilentFloat(attributes.get("rightTurn"), 0);
|
||||
}
|
||||
return rightTurn;
|
||||
}
|
||||
public double getRoundaboutTurn() {
|
||||
if(roundaboutTurn == null) {
|
||||
roundaboutTurn = parseSilentFloat(attributes.get("roundaboutTurn"), 0);
|
||||
}
|
||||
return roundaboutTurn;
|
||||
}
|
||||
@Override
|
||||
|
@ -307,7 +303,7 @@ public class GeneralRouter extends VehicleRouter {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private void specialize(String specializationTag, Map<String, Float> m){
|
||||
private <T> void specialize(String specializationTag, Map<String, T> m){
|
||||
ArrayList<String> ks = new ArrayList<String>(m.keySet());
|
||||
for(String s : ks){
|
||||
if(s.startsWith(specializationTag +":")) {
|
||||
|
@ -319,15 +315,25 @@ public class GeneralRouter extends VehicleRouter {
|
|||
@Override
|
||||
public GeneralRouter specialization(String specializationTag) {
|
||||
GeneralRouter gr = new GeneralRouter(this);
|
||||
gr.specialize(specializationTag, gr.highwayFuturePriorities);
|
||||
gr.specialize(specializationTag, gr.highwayPriorities);
|
||||
gr.specialize(specializationTag, gr.highwaySpeed);
|
||||
gr.specialize(specializationTag, gr.avoid);
|
||||
gr.specialize(specializationTag, gr.obstacles);
|
||||
gr.specialize(specializationTag, gr.routingObstacles);
|
||||
gr.specialize(specializationTag, gr.attributes);
|
||||
return gr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAttribute(String attribute) {
|
||||
return attributes.containsKey(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(String attribute) {
|
||||
return attributes.get(attribute);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,38 +16,31 @@ import org.xml.sax.SAXException;
|
|||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
public class RoutingConfiguration {
|
||||
|
||||
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
||||
public Map<String, String> attributes = new LinkedHashMap<String, String>();
|
||||
|
||||
// 1. parameters of routing and different tweaks
|
||||
// Influence on A* : f(x) + heuristicCoefficient*g(X)
|
||||
public float heuristicCoefficient = 1;
|
||||
|
||||
public static final int DEFAULT_MEMORY_LIMIT = 30;
|
||||
|
||||
|
||||
// 1.1 tile load parameters (should not affect routing)
|
||||
public int ZOOM_TO_LOAD_TILES = 16;
|
||||
public int memoryLimitation;
|
||||
|
||||
// 1.2 Dynamic road prioritizing (heuristic)
|
||||
public boolean useDynamicRoadPrioritising = true;
|
||||
public int dynamicRoadPriorityDistance = 0;
|
||||
|
||||
// 1.3 Relaxing strategy
|
||||
public boolean useRelaxingStrategy = true;
|
||||
public int ITERATIONS_TO_RELAX_NODES = 100;
|
||||
public float RELAX_NODES_IF_START_DIST_COEF = 3;
|
||||
|
||||
// 1.4 Build A* graph in backward/forward direction (can affect results)
|
||||
// 1.2 Build A* graph in backward/forward direction (can affect results)
|
||||
// 0 - 2 ways, 1 - direct way, -1 - reverse way
|
||||
public int planRoadDirection = 0;
|
||||
|
||||
// 1.5 Router specific coefficients and restrictions
|
||||
// 1.3 Router specific coefficients and restrictions
|
||||
public VehicleRouter router = new GeneralRouter(GeneralRouterProfile.CAR, new LinkedHashMap<String, String>());
|
||||
public String routerName = "";
|
||||
|
||||
// 1.6 Used to calculate route in movement
|
||||
// 1.4 Used to calculate route in movement
|
||||
public Double initialDirection;
|
||||
|
||||
|
||||
|
||||
public static class Builder {
|
||||
// Design time storage
|
||||
private String defaultRouter = "";
|
||||
|
@ -62,10 +55,21 @@ public class RoutingConfiguration {
|
|||
router = defaultRouter;
|
||||
}
|
||||
RoutingConfiguration i = new RoutingConfiguration();
|
||||
if (routers.containsKey(router)) {
|
||||
i.router = routers.get(router);
|
||||
if (specialization != null) {
|
||||
for (String s : specialization) {
|
||||
i.router = i.router.specialization(s);
|
||||
}
|
||||
}
|
||||
i.routerName = router;
|
||||
}
|
||||
attributes.put("routerName", router);
|
||||
i.attributes.putAll(attributes);
|
||||
i.initialDirection = direction;
|
||||
i.heuristicCoefficient = parseSilentFloat(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||
int desirable = parseSilentInt(getAttribute(router, "memoryLimitInMB"), 0);
|
||||
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
||||
if(desirable != 0) {
|
||||
i.memoryLimitation = desirable * (1 << 20);
|
||||
} else {
|
||||
|
@ -74,29 +78,15 @@ public class RoutingConfiguration {
|
|||
}
|
||||
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
||||
}
|
||||
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
|
||||
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
|
||||
i.dynamicRoadPriorityDistance = parseSilentInt(getAttribute(router, "dynamicRoadPriorityDistance"), i.dynamicRoadPriorityDistance);
|
||||
i.ITERATIONS_TO_RELAX_NODES = parseSilentInt(getAttribute(router, "iterationsToRelaxRoutes"), i.ITERATIONS_TO_RELAX_NODES);
|
||||
i.RELAX_NODES_IF_START_DIST_COEF = parseSilentFloat(getAttribute(router, "relaxNodesIfStartDistSmallCoeff"), i.RELAX_NODES_IF_START_DIST_COEF);
|
||||
i.planRoadDirection = parseSilentInt(getAttribute(router, "planRoadDirection"), i.planRoadDirection);
|
||||
|
||||
if (!routers.containsKey(router)) {
|
||||
return i;
|
||||
}
|
||||
i.router = routers.get(router);
|
||||
if(specialization != null) {
|
||||
for(String s : specialization) {
|
||||
i.router = i.router.specialization(s);
|
||||
}
|
||||
}
|
||||
i.routerName = router;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private String getAttribute(String router, String propertyName) {
|
||||
if (attributes.containsKey(router + "$" + propertyName)) {
|
||||
return attributes.get(router + "$" + propertyName);
|
||||
private String getAttribute(VehicleRouter router, String propertyName) {
|
||||
if (router.containsAttribute(propertyName)) {
|
||||
return router.getAttribute(propertyName);
|
||||
}
|
||||
return attributes.get(propertyName);
|
||||
}
|
||||
|
@ -151,15 +141,15 @@ public class RoutingConfiguration {
|
|||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
String name = parser.isNamespaceAware() ? localName : qName;
|
||||
previousTag = name;
|
||||
if("osmand_routing_config".equals(name)) {
|
||||
config.defaultRouter = attributes.getValue("defaultProfile");
|
||||
} else if("attribute".equals(name)) {
|
||||
previousKey = attributes.getValue("name");
|
||||
previousTag = name;
|
||||
if (currentSelectedRouter != null) {
|
||||
previousKey = currentSelectedRouter + "$" + previousKey;
|
||||
if(currentRouter != null) {
|
||||
currentRouter.addAttribute(attributes.getValue("name"), attributes.getValue("value"));
|
||||
} else {
|
||||
config.attributes.put(attributes.getValue("name"), attributes.getValue("value"));
|
||||
}
|
||||
config.attributes.put(previousKey, attributes.getValue("value"));
|
||||
} else if("routingProfile".equals(name)) {
|
||||
currentSelectedRouter = attributes.getValue("name");
|
||||
Map<String, String> attrs = new LinkedHashMap<String, String>();
|
||||
|
@ -181,12 +171,12 @@ public class RoutingConfiguration {
|
|||
if (attributes.getValue("priority") != null) {
|
||||
currentRouter.highwayPriorities.put(k, parseSilentFloat(attributes.getValue("priority"), 0));
|
||||
}
|
||||
if (attributes.getValue("dynamicPriority") != null) {
|
||||
currentRouter.highwayFuturePriorities.put(k, parseSilentFloat(attributes.getValue("dynamicPriority"), 0));
|
||||
}
|
||||
if (attributes.getValue("speed") != null) {
|
||||
currentRouter.highwaySpeed.put(k, parseSilentFloat(attributes.getValue("speed"), 0));
|
||||
}
|
||||
if ("attribute".equals(previousTag)) {
|
||||
currentRouter.attributes.put(k, attributes.getValue("value"));
|
||||
}
|
||||
if ("avoid".equals(previousTag)) {
|
||||
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"), 0);
|
||||
if (priority == 0) {
|
||||
|
@ -198,23 +188,18 @@ public class RoutingConfiguration {
|
|||
}
|
||||
|
||||
} else if("road".equals(name)) {
|
||||
previousTag = name;
|
||||
previousKey = attributes.getValue("tag") +"$" + attributes.getValue("value");
|
||||
currentRouter.highwayPriorities.put(previousKey, parseSilentFloat(attributes.getValue("priority"),
|
||||
1));
|
||||
currentRouter.highwayFuturePriorities.put(previousKey, parseSilentFloat(attributes.getValue("dynamicPriority"),
|
||||
1));
|
||||
currentRouter.highwaySpeed.put(previousKey, parseSilentFloat(attributes.getValue("speed"),
|
||||
10));
|
||||
} else if("obstacle".equals(name)) {
|
||||
previousTag = name;
|
||||
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
||||
float penalty = parseSilentFloat(attributes.getValue("penalty"), 0);
|
||||
currentRouter.obstacles.put(previousKey, penalty);
|
||||
float routingPenalty = parseSilentFloat(attributes.getValue("routingPenalty"), penalty );
|
||||
currentRouter.routingObstacles.put(previousKey, routingPenalty);
|
||||
} else if("avoid".equals(name)) {
|
||||
previousTag = name;
|
||||
previousKey = attributes.getValue("tag") + "$" + attributes.getValue("value");
|
||||
float priority = parseSilentFloat(attributes.getValue("decreasedPriority"),
|
||||
0);
|
||||
|
|
|
@ -27,11 +27,11 @@ public abstract class VehicleRouter {
|
|||
return road.getHighway();
|
||||
}
|
||||
|
||||
public abstract boolean containsAttribute(String attribute);
|
||||
|
||||
public abstract String getAttribute(String attribute);
|
||||
|
||||
|
||||
/**
|
||||
* Used for algorithm to multiply h(x) part A* based on current road
|
||||
*/
|
||||
public abstract float getFutureRoadPriority(RouteDataObject road);
|
||||
|
||||
/**
|
||||
* return delay in seconds
|
||||
|
|
|
@ -12,18 +12,6 @@
|
|||
(don't specify here ! it is device dependent) -->
|
||||
<attribute name="memoryLimitInMB" value="155" />
|
||||
|
||||
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
|
||||
<attribute name="useDynamicRoadPrioritising" value="false" />
|
||||
<!-- for first N meters speed multiplied by priority, 0 special number - all rest distance -->
|
||||
<attribute name="dynamicRoadPriorityDistance" value="30000" />
|
||||
|
||||
<!-- 1.3 Relaxing strategy -->
|
||||
<!-- If the furthest routing branch passed distance 3 times more than small branches, small will be relaxed-->
|
||||
<!-- Coefficient is configurable -->
|
||||
<attribute name="useRelaxingStrategy" value="false" />
|
||||
<attribute name="iterationsToRelaxRoutes" value="100" />
|
||||
<attribute name="relaxNodesIfStartDistSmallCoeff" value="5"/>
|
||||
|
||||
<!-- 1.4 Build A* graph in backward/forward direction (can affect results) -->
|
||||
<!-- 0 - 2 ways, 1 - direct way, -1 - reverse way -->
|
||||
<attribute name="planRoadDirection" value="0" />
|
||||
|
|
|
@ -721,7 +721,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
int sx31 = st.getRoad().getPoint31XTile(st.getSegmentStart());
|
||||
int sy31 = st.getRoad().getPoint31YTile(st.getSegmentStart());
|
||||
// FIXME
|
||||
RouteSegmentResult[] searchRoute = ctx.nativeLib.testRoutingInternal(sx31, sy31, ex31, ey31);
|
||||
RouteSegmentResult[] searchRoute = ctx.nativeLib.runNativeRouting(sx31, sy31, ex31, ey31, ctx.config);
|
||||
/*List<RouteSegmentResult> searchRoute = */router.searchRoute(ctx, st, e, inters, false);
|
||||
// this.previousRoute = searchRoute;
|
||||
if (animateRoutingCalculation) {
|
||||
|
|
|
@ -58,13 +58,13 @@ static double squareDist(int x1, int y1, int x2, int y2) {
|
|||
}
|
||||
|
||||
static double h(RoutingContext* ctx, float distanceToFinalPoint, SHARED_PTR<RouteSegment> next) {
|
||||
return distanceToFinalPoint / ctx->getMaxDefaultSpeed();
|
||||
return distanceToFinalPoint / ctx->config.getMaxDefaultSpeed();
|
||||
|
||||
}
|
||||
static double h(RoutingContext* ctx, int targetEndX, int targetEndY,
|
||||
int startX, int startY) {
|
||||
double distance = squareRootDist(startX, startY, targetEndX, targetEndY);
|
||||
return distance / ctx->getMaxDefaultSpeed();
|
||||
return distance / ctx->config.getMaxDefaultSpeed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,7 +220,7 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
|||
// avoid empty segments to connect but mark the point as visited
|
||||
visitedSegments[nt] = SHARED_PTR<RouteSegment>();
|
||||
|
||||
int oneway = ctx->isOneWay(road);
|
||||
int oneway = ctx->config.isOneWay(road);
|
||||
bool minusAllowed;
|
||||
bool plusAllowed;
|
||||
if(ctx->firstRoadId == nt) {
|
||||
|
@ -238,11 +238,11 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
|||
int d = plusAllowed ? 1 : -1;
|
||||
if(segment->parentRoute.get() != NULL) {
|
||||
if(plusAllowed && middle < segment->road->pointsX.size() - 1) {
|
||||
obstaclePlusTime = ctx->calculateTurnTime(segment, segment->road->pointsX.size() - 1,
|
||||
obstaclePlusTime = ctx->config.calculateTurnTime(segment, segment->road->pointsX.size() - 1,
|
||||
segment->parentRoute, segment->parentSegmentEnd);
|
||||
}
|
||||
if(minusAllowed && middle > 0) {
|
||||
obstacleMinusTime = ctx->calculateTurnTime(segment, 0,
|
||||
obstacleMinusTime = ctx->config.calculateTurnTime(segment, 0,
|
||||
segment->parentRoute, segment->parentSegmentEnd);
|
||||
}
|
||||
}
|
||||
|
@ -291,14 +291,14 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
|||
|
||||
// 2.1 calculate possible obstacle plus time
|
||||
if(positive) {
|
||||
double obstacle = ctx->defineRoutingObstacle(road, segmentEnd);
|
||||
double obstacle = ctx->config.defineRoutingObstacle(road, segmentEnd);
|
||||
if (obstacle < 0) {
|
||||
plusAllowed = false;
|
||||
continue;
|
||||
}
|
||||
obstaclePlusTime += obstacle;
|
||||
} else {
|
||||
double obstacle = ctx->defineRoutingObstacle(road, segmentEnd);
|
||||
double obstacle = ctx->config.defineRoutingObstacle(road, segmentEnd);
|
||||
if (obstacle < 0) {
|
||||
minusAllowed = false;
|
||||
continue;
|
||||
|
@ -324,10 +324,10 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
|||
// Using A* routing algorithm
|
||||
// g(x) - calculate distance to that point and calculate time
|
||||
|
||||
double priority = ctx->defineSpeedPriority(road);
|
||||
double speed = ctx->defineSpeed(road) * priority;
|
||||
double priority = ctx->config.defineSpeedPriority(road);
|
||||
double speed = ctx->config.defineSpeed(road) * priority;
|
||||
if (speed == 0) {
|
||||
speed = ctx->getMinDefaultSpeed() * priority;
|
||||
speed = ctx->config.getMinDefaultSpeed() * priority;
|
||||
}
|
||||
double distOnRoadToPass = positive? posSegmentDist : negSegmentDist;
|
||||
double distStartObstacles = segment->distanceFromStart + ( positive ? obstaclePlusTime : obstacleMinusTime) + distOnRoadToPass / speed;
|
||||
|
@ -353,7 +353,7 @@ bool proccessRestrictions(RoutingContext* ctx, SHARED_PTR<RouteDataObject> road,
|
|||
if (!reverseWay && road->restrictions.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
if(!ctx->restrictionsAware()) {
|
||||
if(!ctx->config.restrictionsAware()) {
|
||||
return false;
|
||||
}
|
||||
while (next.get() != NULL) {
|
||||
|
@ -497,7 +497,7 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
|||
return false;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// FIXME replace with adequate method
|
||||
SHARED_PTR<RouteSegment> findRouteSegment(int px, int py, RoutingContext* ctx) {
|
||||
return ctx->loadSegmentAround(px, py);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "common.h"
|
||||
#include "binaryRead.h"
|
||||
|
||||
typedef UNORDERED(map)<string, float> MAP_STR_FLOAT;
|
||||
typedef UNORDERED(map)<string, string> MAP_STR_STR;
|
||||
|
||||
static double measuredDist(int x1, int y1, int x2, int y2) {
|
||||
return getDistance(get31LatitudeY(y1), get31LongitudeX(x1), get31LatitudeY(y2),
|
||||
get31LongitudeX(x2));
|
||||
|
@ -54,7 +57,6 @@ struct FinalRouteSegment {
|
|||
|
||||
|
||||
|
||||
const static int ZOOM_TO_LOAD_TILES = 16;
|
||||
struct RoutingSubregionTile {
|
||||
RouteSubregion subregion;
|
||||
// make it without get/set for fast access
|
||||
|
@ -99,9 +101,245 @@ static int64_t calcRouteId(SHARED_PTR<RouteDataObject> o, int ind) {
|
|||
return (o->id << 10) + ind;
|
||||
}
|
||||
|
||||
typedef std::pair<int, std::pair<string, string> > ROUTE_TRIPLE;
|
||||
struct RoutingConfiguration {
|
||||
// 0 index in triple
|
||||
MAP_STR_FLOAT highwaySpeed ;
|
||||
// 1 index in triple
|
||||
MAP_STR_FLOAT highwayPriorities ;
|
||||
// 2 index in triple
|
||||
MAP_STR_FLOAT avoid ;
|
||||
// 3 index in triple
|
||||
MAP_STR_FLOAT obstacles;
|
||||
// 4 index in triple
|
||||
MAP_STR_FLOAT routingObstacles;
|
||||
// 5 index in triple
|
||||
MAP_STR_STR attributes;
|
||||
|
||||
int zoomToLoad;
|
||||
float heurCoefficient;
|
||||
float maxDefaultSpeed;
|
||||
float minDefaultSpeed;
|
||||
bool restrictions;
|
||||
bool onewayAware;
|
||||
bool followLimitations;
|
||||
int memoryLimitation;
|
||||
int planRoadDirection;
|
||||
string routerName;
|
||||
float initialDirection;
|
||||
string routerProfile;
|
||||
float roundaboutTurn;
|
||||
float leftTurn;
|
||||
float rightTurn;
|
||||
|
||||
float parseFloat(string key, float def) {
|
||||
if(attributes.find(key) != attributes.end() && attributes[key] != "") {
|
||||
return atof(attributes[key].c_str());
|
||||
}
|
||||
return def;
|
||||
}
|
||||
bool parseBool(string key, bool def) {
|
||||
if (attributes.find(key) != attributes.end() && attributes[key] != "") {
|
||||
return attributes[key] == "true";
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
string parseString(string key, string def) {
|
||||
if (attributes.find(key) != attributes.end() && attributes[key] != "") {
|
||||
return attributes[key];
|
||||
}
|
||||
return def;
|
||||
}
|
||||
void defaultParams() {
|
||||
planRoadDirection = (int) parseFloat("planRoadDirection", 0);
|
||||
restrictions = parseBool("restrictionsAware", true);
|
||||
followLimitations = parseBool("followSpeedLimitations", true);
|
||||
onewayAware = parseBool("onewayAware", true);
|
||||
roundaboutTurn = parseFloat("roundaboutTurn", 0);
|
||||
leftTurn = parseFloat("leftTurn", 0);
|
||||
rightTurn = parseFloat("rightTurn", 0);
|
||||
minDefaultSpeed = parseFloat("minDefaultSpeed", 45) / 3.6;
|
||||
maxDefaultSpeed = parseFloat("maxDefaultSpeed", 130) / 3.6;
|
||||
heurCoefficient = parseFloat("heuristicCoefficient", 1);
|
||||
memoryLimitation = (int)parseFloat("memoryLimitInMB", memoryLimitation);
|
||||
zoomToLoad = (int)parseFloat("zoomToLoadTiles", 16);
|
||||
routerName = parseString("name", "default");
|
||||
routerProfile = parseString("baseProfile", "car");
|
||||
}
|
||||
|
||||
RoutingConfiguration(vector<ROUTE_TRIPLE>& config, int memLimit = 30, float initDirection = 0) :
|
||||
memoryLimitation(memLimit), initialDirection(initDirection) {
|
||||
for(int j = 0; j<config.size(); j++) {
|
||||
ROUTE_TRIPLE r = config[j];
|
||||
if(r.first == 0) {
|
||||
highwaySpeed[r.second.first] = atof(r.second.second.c_str());
|
||||
} else if(r.first == 1) {
|
||||
highwayPriorities[r.second.first] = atof(r.second.second.c_str());
|
||||
} else if(r.first == 2) {
|
||||
avoid[r.second.first] = atof(r.second.second.c_str());
|
||||
} else if(r.first == 3) {
|
||||
obstacles[r.second.first] = atof(r.second.second.c_str());
|
||||
} else if(r.first == 4) {
|
||||
routingObstacles[r.second.first] = atof(r.second.second.c_str());
|
||||
} else if(r.first == 5) {
|
||||
string v = r.second.second;
|
||||
attributes[r.second.first] = v;
|
||||
}
|
||||
}
|
||||
defaultParams();
|
||||
}
|
||||
|
||||
bool acceptLine(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
bool accepted = false;
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first=="highway" && highwaySpeed[type.second] > 0) {
|
||||
accepted = true;
|
||||
break;
|
||||
} else if(highwaySpeed[type.first + '$' + type.second] > 0) {
|
||||
accepted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!accepted) {
|
||||
return false;
|
||||
}
|
||||
t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(avoid.find(type.first + '$' + type.second) != avoid.end()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string getHighway(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first=="highway") {
|
||||
return type.second;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
float defineSpeedPriority(SHARED_PTR<RouteDataObject> r) {
|
||||
float priority = 1;
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(highwayPriorities.find(type.first+"$"+type.second) != highwaySpeed.end()) {
|
||||
priority *= highwayPriorities[type.first+"$"+type.second];
|
||||
}
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
float getMinDefaultSpeed() {
|
||||
return minDefaultSpeed;
|
||||
}
|
||||
float getMaxDefaultSpeed() {
|
||||
return maxDefaultSpeed;
|
||||
}
|
||||
|
||||
int isOneWay(SHARED_PTR<RouteDataObject> r) {
|
||||
if(!onewayAware){
|
||||
return 0;
|
||||
}
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first == "oneway") {
|
||||
string v = type.second;
|
||||
if("-1" ==v || "reverse" == v) {
|
||||
return -1;
|
||||
} else if("1" == v || "yes" == v) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
float calculateTurnTime(SHARED_PTR<RouteSegment> segment, int index, SHARED_PTR<RouteSegment> next, int nextIndex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float defineRoutingObstacle(SHARED_PTR<RouteDataObject> road, int segmentEnd) {
|
||||
if(road->pointTypes.size() <= segmentEnd) {
|
||||
return 0;
|
||||
}
|
||||
std::vector<uint32_t> pointTypes = road->pointTypes[segmentEnd];
|
||||
std::vector<uint32_t>::iterator t = pointTypes.begin();
|
||||
for(; t != pointTypes.end(); t++) {
|
||||
tag_value type = road->region->decodingRules[*t];
|
||||
if(routingObstacles.find(type.first + "$" + type.second) != routingObstacles.end()) {
|
||||
return routingObstacles[type.first + "$" + type.second];
|
||||
}
|
||||
}
|
||||
t = pointTypes.begin();
|
||||
for(; t != pointTypes.end(); t++) {
|
||||
tag_value type = road->region->decodingRules[*t];
|
||||
if(routingObstacles.find(type.first + "$" ) != routingObstacles.end()) {
|
||||
return routingObstacles[type.first + "$" ];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool restrictionsAware() {
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
float maxSpeed(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first=="maxspeed") {
|
||||
std::string v = type.second;
|
||||
int i = 0;
|
||||
while(i < v.length() && v[i] >= '0' && v[i] <= '9') {
|
||||
i++;
|
||||
}
|
||||
if(i > 0) {
|
||||
float f = atoi(v.substr(0, i).c_str());
|
||||
f = f / 3.6;
|
||||
if(v.find("mph") != std::string::npos ) {
|
||||
f *= 1.6;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float defineSpeed(SHARED_PTR<RouteDataObject> r) {
|
||||
if (followLimitations) {
|
||||
float m = maxSpeed(r);
|
||||
if(m > 0) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(highwaySpeed.find(type.first+"$"+type.second) != highwaySpeed.end()) {
|
||||
return highwaySpeed[type.first+"$"+type.second] / 3.6;
|
||||
}
|
||||
}
|
||||
return getMinDefaultSpeed();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// FIXME configuration methods
|
||||
struct RoutingContext {
|
||||
int visitedSegments;
|
||||
int loadedTiles;
|
||||
|
@ -109,6 +347,7 @@ struct RoutingContext {
|
|||
ElapsedTimer timeToCalculate;
|
||||
int firstRoadDirection;
|
||||
int64_t firstRoadId;
|
||||
RoutingConfiguration config;
|
||||
|
||||
int startX;
|
||||
int startY;
|
||||
|
@ -122,25 +361,12 @@ struct RoutingContext {
|
|||
UNORDERED(map)<int64_t, SHARED_PTR<RoutingSubregionTile> > subregionTiles;
|
||||
UNORDERED(map)<int64_t, std::vector<SHARED_PTR<RoutingSubregionTile> > > indexedSubregions;
|
||||
|
||||
RoutingContext() : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0){
|
||||
}
|
||||
bool acceptLine(SHARED_PTR<RouteDataObject> r) {
|
||||
string v = getHighway(r);
|
||||
if(v != "" && v != "cycleway" && v != "footway" && v != "steps"){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
RoutingContext(RoutingConfiguration& config) : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0),
|
||||
config(config){
|
||||
}
|
||||
|
||||
string getHighway(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first=="highway") {
|
||||
return type.second;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
bool acceptLine(SHARED_PTR<RouteDataObject> r) {
|
||||
return config.acceptLine(r);
|
||||
}
|
||||
|
||||
void loadHeaderObjects(int64_t tileId) {
|
||||
|
@ -167,7 +393,7 @@ struct RoutingContext {
|
|||
|
||||
void loadHeaders(uint32_t xloc, uint32_t yloc) {
|
||||
timeToLoad.start();
|
||||
int z = ZOOM_TO_LOAD_TILES;
|
||||
int z = config.zoomToLoad;
|
||||
int tz = 31 - z;
|
||||
int64_t tileId = (xloc << z) + yloc;
|
||||
if (indexedSubregions.find(tileId) == indexedSubregions.end()) {
|
||||
|
@ -192,12 +418,12 @@ struct RoutingContext {
|
|||
}
|
||||
|
||||
|
||||
// FIXME
|
||||
// FIXME replace with adequate method
|
||||
SHARED_PTR<RouteSegment> loadSegmentAround(int x31, int y31) {
|
||||
timeToLoad.start();
|
||||
SHARED_PTR<RouteSegment> r;
|
||||
float dist = -1;
|
||||
int z = ZOOM_TO_LOAD_TILES;
|
||||
int z = config.zoomToLoad;
|
||||
uint32_t xloc = x31 >> (31 - z);
|
||||
uint32_t yloc = y31 >> (31 - z);
|
||||
uint64_t l = (((uint64_t) x31) << 31) + (uint64_t) y31;
|
||||
|
@ -227,7 +453,7 @@ struct RoutingContext {
|
|||
|
||||
// void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub)
|
||||
SHARED_PTR<RouteSegment> loadRouteSegment(int x31, int y31) {
|
||||
int z = ZOOM_TO_LOAD_TILES;
|
||||
int z = config.zoomToLoad;
|
||||
int64_t xloc = x31 >> (31 - z);
|
||||
int64_t yloc = y31 >> (31 - z);
|
||||
uint64_t l = (((uint64_t) x31) << 31) + (uint64_t) y31;
|
||||
|
@ -262,157 +488,16 @@ struct RoutingContext {
|
|||
return false;
|
||||
}
|
||||
float getHeuristicCoefficient(){
|
||||
return 1;
|
||||
return config.heurCoefficient;
|
||||
}
|
||||
|
||||
bool planRouteIn2Directions() {
|
||||
return getPlanRoadDirection() == 0;
|
||||
}
|
||||
int getPlanRoadDirection() {
|
||||
return 1;
|
||||
return config.planRoadDirection;
|
||||
}
|
||||
|
||||
float defineSpeedPriority(SHARED_PTR<RouteDataObject> r) {
|
||||
string v = getHighway(r);
|
||||
if(v == "") {
|
||||
return 1;
|
||||
} else if(v == "motorway") {
|
||||
return 1.2;
|
||||
} else if(v == "motorway_link") {
|
||||
return 1.2;
|
||||
} else if(v == "trunk") {
|
||||
return 1.2;
|
||||
} else if(v == "trunk_link") {
|
||||
return 1.2;
|
||||
} else if(v == "primary") {
|
||||
return 1.1;
|
||||
} else if(v == "primary_link") {
|
||||
return 1.1;
|
||||
} else if(v == "secondary") {
|
||||
return 1.05;
|
||||
} else if(v == "secondary_link") {
|
||||
return 1.05;
|
||||
} else if(v == "tertiary") {
|
||||
return 1;
|
||||
} else if(v == "tertiary_link") {
|
||||
return 1;
|
||||
} else if(v == "unclassified") {
|
||||
return 0.7;
|
||||
} else if(v == "road") {
|
||||
return 0.7;
|
||||
} else if(v == "service") {
|
||||
return 0.5;
|
||||
} else if(v == "track") {
|
||||
return 0.3;
|
||||
} else if(v == "residential") {
|
||||
return 0.5;
|
||||
} else if(v == "living_street") {
|
||||
return 0.5;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
float maxSpeed(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++) {
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first=="maxspeed") {
|
||||
std::string v = type.second;
|
||||
int i = 0;
|
||||
while(i < v.length() && v[i] >= '0' && v[i] <= '9') {
|
||||
i++;
|
||||
}
|
||||
if(i > 0) {
|
||||
float f = atoi(v.substr(0, i).c_str());
|
||||
f /= 3.6; // km/h -> m/s
|
||||
if(v.find("mph") != std::string::npos ) {
|
||||
f *= 1.6;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float defineSpeed(SHARED_PTR<RouteDataObject> r) {
|
||||
float speed = maxSpeed(r);
|
||||
if(speed > 0) {
|
||||
return speed;
|
||||
}
|
||||
string v = getHighway(r);
|
||||
if(v == "") {
|
||||
} else if(v == "motorway") {
|
||||
speed = 110;
|
||||
} else if(v == "motorway_link") {
|
||||
speed = 80;
|
||||
} else if(v == "trunk") {
|
||||
speed = 100;
|
||||
} else if(v == "trunk_link") {
|
||||
speed = 75;
|
||||
} else if(v == "primary") {
|
||||
speed = 65;
|
||||
} else if(v == "primary_link") {
|
||||
speed = 50;
|
||||
} else if(v == "secondary") {
|
||||
speed = 60;
|
||||
} else if(v == "secondary_link") {
|
||||
speed = 50;
|
||||
} else if(v == "tertiary") {
|
||||
speed = 45;
|
||||
} else if(v == "tertiary_link") {
|
||||
speed = 40;
|
||||
} else if(v == "unclassified") {
|
||||
speed = 35;
|
||||
} else if(v == "road") {
|
||||
speed = 35;
|
||||
} else if(v == "service") {
|
||||
speed = 30;
|
||||
} else if(v == "track") {
|
||||
speed = 15;
|
||||
} else if(v == "residential") {
|
||||
speed = 35;
|
||||
} else if(v == "living_street") {
|
||||
speed = 25;
|
||||
}
|
||||
return speed / 3.;
|
||||
}
|
||||
|
||||
|
||||
float getMinDefaultSpeed(){
|
||||
return 40 / 3.6;
|
||||
}
|
||||
float getMaxDefaultSpeed(){
|
||||
return 130 / 3.6;
|
||||
}
|
||||
|
||||
int isOneWay(SHARED_PTR<RouteDataObject> r) {
|
||||
std::vector<uint32_t>::iterator t = r->types.begin();
|
||||
for(; t != r->types.end(); t++){
|
||||
tag_value type = r->region->decodingRules[*t];
|
||||
if(type.first == "oneway") {
|
||||
string v = type.second;
|
||||
if("-1" ==v || "reverse" == v) {
|
||||
return -1;
|
||||
} else if("1" == v || "yes" == v) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float calculateTurnTime(SHARED_PTR<RouteSegment> segment, int index, SHARED_PTR<RouteSegment> next, int nextIndex){
|
||||
return 0;
|
||||
}
|
||||
float defineRoutingObstacle(SHARED_PTR<RouteDataObject> road, int segmentEnd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool restrictionsAware(){
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -580,15 +580,33 @@ extern "C" JNIEXPORT void JNICALL Java_net_osmand_NativeLibrary_deleteRouteSearc
|
|||
}
|
||||
delete t;
|
||||
}
|
||||
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_testRouting(JNIEnv* ienv,
|
||||
jobject obj, jint sx31,
|
||||
jint sy31, jint ex31, jint ey31) {
|
||||
RoutingContext c;
|
||||
c.startX = sx31;
|
||||
c.startY = sy31;
|
||||
c.endX = ex31;
|
||||
c.endY = ey31;
|
||||
//p RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig);
|
||||
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRouting(JNIEnv* ienv,
|
||||
jobject obj, jintArray coordinates,
|
||||
jintArray stateConfig, jobjectArray keyConfig, jobjectArray valueConfig) {
|
||||
|
||||
vector<ROUTE_TRIPLE> cfg;
|
||||
int* data = ienv->GetIntArrayElements(stateConfig, NULL);
|
||||
for(int k = 0; k < ienv->GetArrayLength(stateConfig); k++) {
|
||||
ROUTE_TRIPLE t = ROUTE_TRIPLE (data[k], std::pair<string, string>(
|
||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(keyConfig, k)),
|
||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(valueConfig, k)))
|
||||
);
|
||||
cfg.push_back(t);
|
||||
}
|
||||
ienv->ReleaseIntArrayElements(stateConfig, data, 0);
|
||||
|
||||
RoutingConfiguration config(cfg);
|
||||
RoutingContext c(config);
|
||||
data = ienv->GetIntArrayElements(coordinates, NULL);
|
||||
c.startX = data[0];
|
||||
c.startY = data[1];
|
||||
c.endX = data[2];
|
||||
c.endY = data[3];
|
||||
ienv->ReleaseIntArrayElements(coordinates, data, 0);
|
||||
|
||||
vector<RouteSegmentResult> r = searchRouteInternal(&c, false);
|
||||
// convert results
|
||||
jobjectArray res = ienv->NewObjectArray(r.size(), jclass_RouteSegmentResult, NULL);
|
||||
for (int i = 0; i < r.size(); i++) {
|
||||
jobject robj = convertRouteDataObjectToJava(ienv, r[i].object.get(), NULL);
|
||||
|
|
|
@ -160,11 +160,9 @@ void printFileInformation(const char* fileName, VerboseInfo* verbose) {
|
|||
i, j++, rt->minZoom, rt->maxZoom, rt->length, ch);
|
||||
}
|
||||
if ((verbose != NULL && verbose->vmap)) {
|
||||
// FIXME
|
||||
//printMapDetailInfo(verbose, index);
|
||||
}
|
||||
} else if (it->type == TRANSPORT_INDEX) {
|
||||
// FIXME
|
||||
// TransportIndex ti = ((TransportIndex) p);
|
||||
// int sh = (31 - BinaryMapIndexReader.TRANSPORT_STOP_ZOOM);
|
||||
// println(
|
||||
|
|
Loading…
Reference in a new issue