Introduce routing configuration

This commit is contained in:
Victor Shcherb 2012-06-16 12:06:04 +02:00
parent d0ee3ef290
commit 515db46f75
16 changed files with 606 additions and 729 deletions

View file

@ -50,6 +50,14 @@ public class BinaryMapRouteReaderAdapter {
analyze();
}
public String getTag() {
return t;
}
public String getValue(){
return v;
}
public boolean roundabout(){
return type == ROUNDABOUT;
}

View file

@ -1,159 +0,0 @@
package net.osmand.router;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.binary.RouteDataObject;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
public class BicycleRouter extends VehicleRouter {
// no distinguish for speed in city/outside city (for now)
private Map<String, Double> bicycleNotDefinedValues = new LinkedHashMap<String, Double>();
private Map<String, Double> bicyclePriorityValues = new LinkedHashMap<String, Double>();
// in m/s
{
bicycleNotDefinedValues.put("motorway", 6d);
bicycleNotDefinedValues.put("motorway_link", 6d);
bicycleNotDefinedValues.put("trunk", 6d);
bicycleNotDefinedValues.put("trunk_link", 6d);
bicycleNotDefinedValues.put("primary", 6d);
bicycleNotDefinedValues.put("primary_link", 6d);
bicycleNotDefinedValues.put("secondary", 6d);
bicycleNotDefinedValues.put("secondary_link", 6d);
bicycleNotDefinedValues.put("tertiary", 6d);
bicycleNotDefinedValues.put("tertiary_link", 6d);
bicycleNotDefinedValues.put("residential", 6d);
bicycleNotDefinedValues.put("road", 6d);
bicycleNotDefinedValues.put("service", 5d);
bicycleNotDefinedValues.put("unclassified", 5d);
bicycleNotDefinedValues.put("track", 4d);
bicycleNotDefinedValues.put("path", 4d);
bicycleNotDefinedValues.put("living_street", 5d);
bicycleNotDefinedValues.put("pedestrian", 3d);
bicycleNotDefinedValues.put("footway", 4d);
bicycleNotDefinedValues.put("byway", 4d);
bicycleNotDefinedValues.put("cycleway", 6d);
bicycleNotDefinedValues.put("bridleway", 3d);
bicycleNotDefinedValues.put("services", 5d);
bicycleNotDefinedValues.put("steps", 1d);
bicyclePriorityValues.put("motorway", 0.7);
bicyclePriorityValues.put("motorway_link", 0.7);
bicyclePriorityValues.put("trunk", 0.7);
bicyclePriorityValues.put("trunk_link", 0.7);
bicyclePriorityValues.put("primary", 0.9);
bicyclePriorityValues.put("primary_link", 0.9);
bicyclePriorityValues.put("secondary", 1d);
bicyclePriorityValues.put("secondary_link", 1.0d);
bicyclePriorityValues.put("tertiary", 1.0d);
bicyclePriorityValues.put("tertiary_link", 1.0d);
bicyclePriorityValues.put("residential", 1d);
bicyclePriorityValues.put("service", 1d);
bicyclePriorityValues.put("unclassified", 0.9d);
bicyclePriorityValues.put("road", 1d);
bicyclePriorityValues.put("track", 0.9d);
bicyclePriorityValues.put("path", 0.9d);
bicyclePriorityValues.put("living_street", 1d);
bicyclePriorityValues.put("pedestrian", 0.9d);
bicyclePriorityValues.put("footway", 0.9d);
bicyclePriorityValues.put("byway", 1d);
bicyclePriorityValues.put("cycleway", 1.3d);
bicyclePriorityValues.put("bridleway", 0.8d);
bicyclePriorityValues.put("services", 1d);
bicyclePriorityValues.put("steps", 0.6d);
}
@Override
public boolean acceptLine(RouteDataObject way) {
return bicycleNotDefinedValues.containsKey(way.getHighway());
}
/**
* return delay in seconds
*/
@Override
public double defineObstacle(RouteDataObject road, int point) {
int[] pointTypes = road.getPointTypes(point);
if(pointTypes == null) {
return 0;
}
RouteRegion reg = road.region;
int sz = pointTypes.length;
for(int i=0; i<sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes[i]);
if(r.getType() == RouteTypeRule.TRAFFIC_SIGNALS) {
return 30;
} else if(r.getType() == RouteTypeRule.RAILWAY_CROSSING) {
return 15;
}
}
return 0;
}
@Override
public double getFutureRoadPriority(RouteDataObject road) {
String highway = getHighway(road);
double priority = bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 1d;
return priority;
}
/**
* return speed in m/s
*/
@Override
public double defineSpeed(RouteDataObject road) {
Double value = bicycleNotDefinedValues.get(getHighway(road));
if (value == null) {
value = 4d;
}
return value / 3.6d ;
}
@Override
public double defineSpeedPriority(RouteDataObject road) {
String highway = getHighway(road);
double priority = bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 0.5d;
return priority;
}
/**
* Used for A* routing to calculate g(x)
*
* @return minimal speed at road
*/
@Override
public double getMinDefaultSpeed() {
return 2;
}
/**
* Used for A* routing to predict h(x) : it should be great than (!) any g(x)
*
* @return maximum speed to calculate shortest distance
*/
@Override
public double getMaxDefaultSpeed() {
return 6;
}
@Override
public double calculateTurnTime(RouteSegment segment, RouteSegment next, int segmentEnd) {
boolean end = (segmentEnd == segment.road.getPointsLength() - 1 || segmentEnd == 0);
boolean start = next.segmentStart == 0;
if (end) {
if(!start){
return 5;
}
return 0;
} else {
return 5;
}
}
}

View file

@ -249,7 +249,7 @@ public class BinaryRoutePlanner {
}
} else {
// different strategy : use onedirectional graph
inverse = !ctx.getPlanRoadDirection().booleanValue();
inverse = ctx.getPlanRoadDirection() < 0;
}
if (inverse) {
graphSegments = graphReverseSegments;
@ -258,7 +258,7 @@ public class BinaryRoutePlanner {
}
if(ctx.runTilesGC()) {
unloadUnusedTiles(ctx, ctx.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
unloadUnusedTiles(ctx, ctx.config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
}
if(ctx.runRelaxingStrategy()) {
relaxNotNeededSegments(ctx, graphDirectSegments, true);
@ -327,7 +327,7 @@ public class BinaryRoutePlanner {
mine = s.distanceToEnd;
}
}
double d = mine * 3;
double d = mine * ctx.config.ITERATIONS_TO_RELAX_NODES;
iterator = graphSegments.iterator();
while (iterator.hasNext()) {
RouteSegment s = iterator.next();
@ -623,6 +623,9 @@ public class BinaryRoutePlanner {
if (!reverseWay && road.getRestrictionLength() > 0) {
return false;
}
if(!ctx.getRouter().restrictionsAwayre()) {
return false;
}
while (next != null) {
int type = -1;
if (!reverseWay) {
@ -831,9 +834,9 @@ public class BinaryRoutePlanner {
double startLon = MapUtils.get31LongitudeX(start.road.getPoint31XTile(start.segmentStart));
double endLat = MapUtils.get31LatitudeY(end.road.getPoint31YTile(end.segmentStart));
double endLon = MapUtils.get31LongitudeX(end.road.getPoint31XTile(end.segmentStart));
println(MessageFormat.format("<test regions=\"\" description=\"\" best_percent=\"\" vehicle=\"\" \n" +
println(MessageFormat.format("<test regions=\"\" description=\"\" best_percent=\"\" vehicle=\"{5}\" \n" +
" start_lat=\"{0}\" start_lon=\"{1}\" target_lat=\"{2}\" target_lon=\"{3}\" complete_time=\"{4}\">",
startLat+"", startLon+"", endLat+"", endLon+"", completeTime+""));
startLat+"", startLon+"", endLat+"", endLon+"", completeTime+"", ctx.config.routerName));
for (RouteSegmentResult res : result) {
String name = "Unknown";//res.object.getName();
String ref = "";//res.object.getNameByType(res.object.getMapIndex().refEncodingType);

View file

@ -1,202 +0,0 @@
package net.osmand.router;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.binary.RouteDataObject;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
public class CarRouter extends VehicleRouter {
// no distinguish for speed in city/outside city (for now)
private Map<String, Double> autoNotDefinedValues = new LinkedHashMap<String, Double>();
private Map<String, Double> autoPriorityValues = new LinkedHashMap<String, Double>();
{
autoNotDefinedValues.put("motorway", 110d);
autoNotDefinedValues.put("motorway_link", 80d);
autoNotDefinedValues.put("trunk", 100d);
autoNotDefinedValues.put("trunk_link", 80d);
autoNotDefinedValues.put("primary", 65d);//generally linking larger towns.
autoNotDefinedValues.put("primary_link", 45d);
autoNotDefinedValues.put("secondary", 50d);//generally linking smaller towns and villages
autoNotDefinedValues.put("secondary_link", 40d);
autoNotDefinedValues.put("tertiary", 35d);//important urban roads
autoNotDefinedValues.put("tertiary_link", 30d);
autoNotDefinedValues.put("unclassified", 30d);//lowest form of grid network, usually 90% of urban roads
autoNotDefinedValues.put("road", 30d);//road = no type, no review and may be not accurate
autoNotDefinedValues.put("residential", 20d);//primarily for access to properties, small roads with 1/2 intersections
autoNotDefinedValues.put("service", 15d);//parking + private roads
autoNotDefinedValues.put("track", 15d);//very bad roads
autoNotDefinedValues.put("path", 10d);//may not be usable by cars!!
autoNotDefinedValues.put("living_street", 10d);//too small for cars usually
//car are able to enter in highway=pedestrian with restrictions
autoPriorityValues.put("motorway", 1.5);
autoPriorityValues.put("motorway_link", 1.3);
autoPriorityValues.put("trunk", 1.5);
autoPriorityValues.put("trunk_link", 1.3);
autoPriorityValues.put("primary", 1.3d);
autoPriorityValues.put("primary_link", 1.1d);
autoPriorityValues.put("secondary", 1.1d);
autoPriorityValues.put("secondary_link", 1.0d);
autoPriorityValues.put("tertiary", 0.85d);
autoPriorityValues.put("tertiary_link", 0.85d);
autoPriorityValues.put("unclassified", 0.7d);
autoPriorityValues.put("residential", 0.4d);
autoPriorityValues.put("road", 0.4d);
autoPriorityValues.put("service", 0.2d);
autoPriorityValues.put("track", 0.2d);
autoPriorityValues.put("path", 0.1d);
autoPriorityValues.put("living_street", 0.1d);
}
@Override
public boolean acceptLine(RouteDataObject way) {
return autoNotDefinedValues.containsKey(way.getHighway());
}
/**
* return delay in seconds
*/
@Override
public double defineObstacle(RouteDataObject road, int point) {
int[] pointTypes = road.getPointTypes(point);
if(pointTypes == null) {
return 0;
}
RouteRegion reg = road.region;
int sz = pointTypes.length;
for(int i=0; i<sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes[i]);
if(r.getType() == RouteTypeRule.TRAFFIC_SIGNALS) {
return 35;
} else if(r.getType() == RouteTypeRule.RAILWAY_CROSSING) {
return 20;
}
}
return 0;
}
@Override
public double getFutureRoadPriority(RouteDataObject road) {
String highway = getHighway(road);
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
// keep it in boundaries otherwise
// (it will use first founded exist for trunk even if it in another city and make Uturn there)
if (priority > 1.4) {
return 1.4d;
} else if (priority < 0.5d) {
return 0.5d;
}
return priority;
};
/**
* return speed in m/s
*/
@Override
public double defineSpeed(RouteDataObject road) {
String highway = null;
RouteRegion reg = road.region;
int sz = road.types.length;
for (int i = 0; i < sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(road.types[i]);
float maxSpeed = r.maxSpeed();
if (maxSpeed > 0) {
return maxSpeed;
} else if (highway == null) {
highway = r.highwayRoad();
}
}
Double value = autoNotDefinedValues.get(highway);
if (value == null) {
value = 45d;
}
return value / 3.6d;
}
@Override
public double defineSpeedPriority(RouteDataObject road) {
String highway = road.getHighway();
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
return priority;
}
/**
* Used for A* routing to calculate g(x)
*
* @return minimal speed at road
*/
@Override
public double getMinDefaultSpeed() {
return 12;
}
/**
* Used for A* routing to predict h(x) : it should be < (!) any g(x)
*
* @return maximum speed to calculate shortest distance
*/
@Override
public double getMaxDefaultSpeed() {
return 30;
}
private double directionRoute(RouteSegment segment, int segmentEnd, boolean opp){
boolean plus = segmentEnd == 0;
int x = segment.road.getPoint31XTile(segmentEnd);
int y = segment.road.getPoint31YTile(segmentEnd);
int nx = segmentEnd;
int px = x;
int py = y;
do {
if(plus){
nx++;
if(nx >= segment.road.getPointsLength()){
break;
}
} else {
nx--;
if(nx < 0){
break;
}
}
px = segment.road.getPoint31XTile(nx);
py = segment.road.getPoint31YTile(nx);
} while(Math.abs(px - x) + Math.abs(py - y) < 100);
if(opp){
return Math.atan2(py - y, px - x);
} else {
return Math.atan2(y - py, x - px);
}
}
@Override
public double calculateTurnTime(RouteSegment segment, RouteSegment next, int segmentEnd) {
boolean end = (segmentEnd == segment.road.getPointsLength() - 1 || segmentEnd == 0);
boolean start = next.segmentStart == 0 || next.segmentStart == next.getRoad().getPointsLength() - 1;
// that addition highly affects to trunk roads !(prefer trunk/motorway)
if (end && start) {
// next.road.getId() >> 1 != segment.road.getId() >> 1
if (next.road.getPointsLength() > 1) {
double a1 = directionRoute(segment, segmentEnd, false);
double a2 = directionRoute(next, next.segmentStart, true);
double diff = Math.abs(a1 - a2);
if (diff > Math.PI / 2 && diff < 3 * Math.PI / 2) {
return 20;
}
}
return 0;
} else {
return 15;
}
}
}

View file

@ -0,0 +1,166 @@
package net.osmand.router;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.binary.RouteDataObject;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
public class GeneralRouter extends VehicleRouter {
Map<String, Double> highwaySpeed = new LinkedHashMap<String, Double>();
Map<String, Double> highwayPriorities = new LinkedHashMap<String, Double>();
Map<String, Double> highwayFuturePriorities = new LinkedHashMap<String, Double>();
Map<String, Double> obstacles = new LinkedHashMap<String, Double>();
boolean followSpeedLimitations = true;
boolean restrictionsAware = true;
boolean onewayAware = true;
double minDefaultSpeed = 10;
double maxDefaultSpeed = 10;
double leftTurn = 0;
double rightTurn = 0;
GeneralRouterProfile profile;
public enum GeneralRouterProfile {
CAR,
PEDESTRIAN,
BICYCLE
}
@Override
public boolean acceptLine(RouteDataObject way) {
return highwaySpeed.containsKey(way.getHighway());
}
@Override
public boolean restrictionsAwayre() {
return restrictionsAware;
}
@Override
public double defineObstacle(RouteDataObject road, int point) {
int[] pointTypes = road.getPointTypes(point);
if(pointTypes == null) {
return 0;
}
RouteRegion reg = road.region;
int sz = pointTypes.length;
for(int i=0; i<sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes[i]);
String key = r.getTag() + "$" + r.getValue();
Double v = obstacles.get(key);
if(v != null ){
return v;
}
}
return 0;
}
@Override
public int isOneWay(RouteDataObject road) {
if (!onewayAware) {
return 0;
}
return super.isOneWay(road);
}
@Override
public double getFutureRoadPriority(RouteDataObject road) {
String highway = road.getHighway();
double priority = highway != null && highwayFuturePriorities.containsKey(highway) ? highwayFuturePriorities.get(highway) : 1d;
return priority;
}
@Override
public double defineSpeed(RouteDataObject road) {
if (followSpeedLimitations) {
RouteRegion reg = road.region;
int sz = road.types.length;
for (int i = 0; i < sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(road.types[i]);
float maxSpeed = r.maxSpeed();
if (maxSpeed > 0) {
return maxSpeed;
}
}
}
Double value = highwaySpeed.get(road.getHighway());
if (value == null) {
value = minDefaultSpeed;
}
return value / 3.6d;
}
@Override
public double defineSpeedPriority(RouteDataObject road) {
String highway = road.getHighway();
double priority = highway != null && highwayPriorities.containsKey(highway) ? highwayPriorities.get(highway) : 1d;
return priority;
}
@Override
public double getMinDefaultSpeed() {
return minDefaultSpeed / 3.6d;
}
@Override
public double getMaxDefaultSpeed() {
return maxDefaultSpeed / 3.6d;
}
private double directionRoute(RouteSegment segment, int segmentEnd, boolean opp){
boolean plus = segmentEnd == 0;
int x = segment.road.getPoint31XTile(segmentEnd);
int y = segment.road.getPoint31YTile(segmentEnd);
int nx = segmentEnd;
int px = x;
int py = y;
do {
if(plus){
nx++;
if(nx >= segment.road.getPointsLength()){
break;
}
} else {
nx--;
if(nx < 0){
break;
}
}
px = segment.road.getPoint31XTile(nx);
py = segment.road.getPoint31YTile(nx);
} while(Math.abs(px - x) + Math.abs(py - y) < 100);
if(opp){
return Math.atan2(py - y, px - x);
} else {
return Math.atan2(y - py, x - px);
}
}
@Override
public double calculateTurnTime(RouteSegment segment, RouteSegment next, int segmentEnd) {
if (leftTurn > 0 || rightTurn > 0) {
if (next.road.getPointsLength() > 1) {
double a1 = directionRoute(segment, segmentEnd, false);
double a2 = directionRoute(next, next.segmentStart, true);
double diff = Math.abs(a1 - a2);
// more like UT
if (diff > 3 * Math.PI / 4 && diff < 5 * Math.PI / 4) {
return leftTurn;
}
if (diff > Math.PI / 3 && diff <= 3 * Math.PI / 4) {
return rightTurn;
}
if (diff < 2 * Math.PI / 3 && diff >= 3 * Math.PI / 4) {
return leftTurn;
}
}
return 0;
}
return 0;
}
}

View file

@ -1,164 +0,0 @@
package net.osmand.router;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.binary.RouteDataObject;
import net.osmand.osm.MapRenderingTypes;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
public class PedestrianRouter extends VehicleRouter {
// no distinguish for speed in city/outside city (for now)
private Map<String, Double> pedestrianNotDefinedValues = new LinkedHashMap<String, Double>();
private Map<String, Double> pedestrianPriorityValues = new LinkedHashMap<String, Double>();
// in m/s
{
pedestrianNotDefinedValues.put("motorway", 1.2d);
pedestrianNotDefinedValues.put("motorway_link", 1.2d);
pedestrianNotDefinedValues.put("trunk", 1.2d);
pedestrianNotDefinedValues.put("trunk_link", 1.2d);
pedestrianNotDefinedValues.put("primary", 1.3d);
pedestrianNotDefinedValues.put("primary_link", 1.3d);
pedestrianNotDefinedValues.put("secondary", 1.4d);
pedestrianNotDefinedValues.put("secondary_link", 1.4d);
pedestrianNotDefinedValues.put("tertiary", 1.8d);
pedestrianNotDefinedValues.put("tertiary_link", 1.8d);
pedestrianNotDefinedValues.put("residential", 1.8d);
pedestrianNotDefinedValues.put("road", 1.8d);
pedestrianNotDefinedValues.put("service", 1.8d);
pedestrianNotDefinedValues.put("unclassified", 1.8d);
pedestrianNotDefinedValues.put("track", 1.5d);
pedestrianNotDefinedValues.put("path", 1.5d);
pedestrianNotDefinedValues.put("living_street", 2d);
pedestrianNotDefinedValues.put("pedestrian", 2d);
pedestrianNotDefinedValues.put("footway", 2d);
pedestrianNotDefinedValues.put("byway", 1.8d);
pedestrianNotDefinedValues.put("cycleway", 1.8d);
pedestrianNotDefinedValues.put("bridleway", 1.8d);
pedestrianNotDefinedValues.put("services", 1.8d);
pedestrianNotDefinedValues.put("steps", 1.3d);
pedestrianPriorityValues.put("motorway", 0.7);
pedestrianPriorityValues.put("motorway_link", 0.7);
pedestrianPriorityValues.put("trunk", 0.7);
pedestrianPriorityValues.put("trunk_link", 0.7);
pedestrianPriorityValues.put("primary", 0.8);
pedestrianPriorityValues.put("primary_link", 0.8);
pedestrianPriorityValues.put("secondary", 0.8);
pedestrianPriorityValues.put("secondary_link", 0.8d);
pedestrianPriorityValues.put("tertiary", 0.9d);
pedestrianPriorityValues.put("tertiary_link", 0.9d);
pedestrianPriorityValues.put("residential", 1d);
pedestrianPriorityValues.put("service", 1d);
pedestrianPriorityValues.put("unclassified", 1d);
pedestrianPriorityValues.put("road", 1d);
pedestrianPriorityValues.put("track", 1d);
pedestrianPriorityValues.put("path", 1d);
pedestrianPriorityValues.put("living_street", 1d);
pedestrianPriorityValues.put("pedestrian", 1.2d);
pedestrianPriorityValues.put("footway", 1.2d);
pedestrianPriorityValues.put("byway", 1d);
pedestrianPriorityValues.put("cycleway", 0.9d);
pedestrianPriorityValues.put("bridleway", 0.9d);
pedestrianPriorityValues.put("services", 1d);
pedestrianPriorityValues.put("steps", 1.2d);
}
@Override
public double getFutureRoadPriority(RouteDataObject road) {
String highway = getHighway(road);
double priority = pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
return priority;
}
@Override
public double defineSpeedPriority(RouteDataObject road) {
String highway = getHighway(road);
double priority = pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
return priority;
}
@Override
public int isOneWay(RouteDataObject road) {
return 0;
}
@Override
public boolean acceptLine(RouteDataObject way) {
return pedestrianNotDefinedValues.containsKey(way.getHighway());
}
public boolean isOneWay(int highwayAttributes) {
return MapRenderingTypes.isOneWayWay(highwayAttributes) || MapRenderingTypes.isRoundabout(highwayAttributes);
}
/**
* return delay in seconds
*/
@Override
public double defineObstacle(RouteDataObject road, int point) {
int[] pointTypes = road.getPointTypes(point);
if(pointTypes == null) {
return 0;
}
RouteRegion reg = road.region;
int sz = pointTypes.length;
for(int i=0; i<sz; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes[i]);
if(r.getType() == RouteTypeRule.TRAFFIC_SIGNALS) {
return 20;
} else if(r.getType() == RouteTypeRule.RAILWAY_CROSSING) {
return 15;
}
}
return 0;
}
/**
* return speed in m/s
*/
@Override
public double defineSpeed(RouteDataObject road) {
double speed = 1.5d;
String highway = getHighway(road);
if (highway != null) {
Double value = pedestrianNotDefinedValues.get(highway);
if (value != null) {
speed = value;
}
}
return speed;
}
/**
* Used for A* routing to calculate g(x)
*
* @return minimal speed at road
*/
@Override
public double getMinDefaultSpeed() {
return 1;
}
/**
* Used for A* routing to predict h(x) : it should be great than (!) any g(x)
*
* @return maximum speed to calculate shortest distance
*/
@Override
public double getMaxDefaultSpeed() {
return 1.8;
}
@Override
public double calculateTurnTime(RouteSegment segment, RouteSegment next, int j) {
return 0;
}
}

View file

@ -0,0 +1,180 @@
package net.osmand.router;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class RoutingConfiguration {
// 1. parameters of routing and different tweaks
// Influence on A* : f(x) + heuristicCoefficient*g(X)
public double heuristicCoefficient = 1;
// 1.1 tile load parameters (should not affect routing)
public int ZOOM_TO_LOAD_TILES = 13; // 12?, 14?
public int ITERATIONS_TO_RUN_GC = 100;
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 25;
// 1.2 Dynamic road prioritizing (heuristic)
public boolean useDynamicRoadPrioritising = true;
// 1.3 Relaxing strategy
public boolean useRelaxingStrategy = true;
public int ITERATIONS_TO_RELAX_NODES = 100;
public double RELAX_NODES_IF_START_DIST_COEF = 3;
// 1.4 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
public VehicleRouter router = new GeneralRouter();
public String routerName = "";
public static class Builder {
// Design time storage
private String defaultRouter = "";
private Map<String, VehicleRouter> routers = new LinkedHashMap<String, VehicleRouter>();
private Map<String, String> attributes = new LinkedHashMap<String, String>();
public RoutingConfiguration initConfig(String router, boolean useShortestWay) {
if (!routers.containsKey(router)) {
router = defaultRouter;
}
RoutingConfiguration i = new RoutingConfiguration();
i.heuristicCoefficient = parseSilentDouble(getAttribute(router, "heuristicCoefficient"), i.heuristicCoefficient);
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
i.ITERATIONS_TO_RUN_GC = parseSilentInt(getAttribute(router, "iterationsToRunGC"), i.ITERATIONS_TO_RUN_GC);
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = parseSilentInt(getAttribute(router, "desirableTilesInMemory"),
i.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY);
i.useDynamicRoadPrioritising = parseSilentBoolean(getAttribute(router, "useDynamicRoadPrioritising"), i.useDynamicRoadPrioritising);
i.useRelaxingStrategy = parseSilentBoolean(getAttribute(router, "useRelaxingStrategy"), i.useRelaxingStrategy);
i.ITERATIONS_TO_RELAX_NODES = parseSilentInt(getAttribute(router, "iterationsToRelaxRoutes"), i.ITERATIONS_TO_RELAX_NODES);
i.RELAX_NODES_IF_START_DIST_COEF = parseSilentDouble(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);
i.routerName = router;
return i;
}
private String getAttribute(String router, String propertyName) {
if (attributes.containsKey(router + "$" + propertyName)) {
return attributes.get(router + "$" + propertyName);
}
return attributes.get(propertyName);
}
}
private static int parseSilentInt(String t, int v) {
if (t == null) {
return v;
}
return Integer.parseInt(t);
}
private static boolean parseSilentBoolean(String t, boolean v) {
if (t == null) {
return v;
}
return Boolean.parseBoolean(t);
}
private static double parseSilentDouble(String t, double v) {
if (t == null) {
return v;
}
return Double.parseDouble(t);
}
private static RoutingConfiguration.Builder DEFAULT;
public static RoutingConfiguration.Builder getDefault() {
if (DEFAULT == null) {
try {
DEFAULT = parseFromInputStream(RoutingConfiguration.class.getResourceAsStream("routing.xml"));
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
return DEFAULT;
}
public static RoutingConfiguration.Builder parseFromInputStream(InputStream is) throws SAXException, IOException {
try {
final SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
final RoutingConfiguration.Builder config = new RoutingConfiguration.Builder();
DefaultHandler handler = new DefaultHandler() {
String currentSelectedRouter = null;
GeneralRouter currentRouter = null;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
String name = parser.isNamespaceAware() ? localName : qName;
if("osmand_routing_config".equals(name)) {
config.defaultRouter = attributes.getValue("defaultProfile");
} else if("attribute".equals(name)) {
String key = attributes.getValue("name");
if(currentSelectedRouter != null) {
key = currentSelectedRouter +"$"+key;
}
config.attributes.put(key, attributes.getValue("value"));
} else if("routingProfile".equals(name)) {
currentSelectedRouter = attributes.getValue("name");
currentRouter = new GeneralRouter();
currentRouter.profile = GeneralRouterProfile.valueOf(attributes.getValue("baseProfile").toUpperCase());
config.routers.put(currentSelectedRouter, currentRouter);
currentRouter.restrictionsAware = parseSilentBoolean(attributes.getValue("restrictionsAware"),
currentRouter.restrictionsAware);
currentRouter.followSpeedLimitations = parseSilentBoolean(attributes.getValue("followSpeedLimitations"),
currentRouter.followSpeedLimitations);
currentRouter.onewayAware = parseSilentBoolean(attributes.getValue("onewayAware"),
currentRouter.onewayAware);
currentRouter.minDefaultSpeed = parseSilentDouble(attributes.getValue("minDefaultSpeed"),
currentRouter.minDefaultSpeed);
currentRouter.maxDefaultSpeed = parseSilentDouble(attributes.getValue("maxDefaultSpeed"),
currentRouter.maxDefaultSpeed);
currentRouter.leftTurn = parseSilentDouble(attributes.getValue("leftTurn"),
currentRouter.leftTurn);
currentRouter.rightTurn = parseSilentDouble(attributes.getValue("rightTurn"),
currentRouter.rightTurn);
} else if("highway".equals(name)) {
String key = attributes.getValue("value");
currentRouter.highwayPriorities.put(key, parseSilentDouble(attributes.getValue("priority"),
1));
currentRouter.highwayFuturePriorities.put(key, parseSilentDouble(attributes.getValue("dynamicPriority"),
1));
currentRouter.highwaySpeed.put(key, parseSilentDouble(attributes.getValue("speed"),
currentRouter.minDefaultSpeed));
} else if("obstacle".equals(name)) {
String key = attributes.getValue("tag") + "$" + attributes.getValue("value");
currentRouter.obstacles.put(key, parseSilentDouble(attributes.getValue("penalty"),
0));
}
}
};
parser.parse(is, handler);
return config;
} catch (ParserConfigurationException e) {
throw new SAXException(e);
}
}
}

View file

@ -18,34 +18,10 @@ import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
public class RoutingContext {
// 1. parameters of routing and different tweaks
// Influence on A* : f(x) + heuristicCoefficient*g(X)
private double heuristicCoefficient = 1;
// 1.1 tile load parameters (should not affect routing)
public int ZOOM_TO_LOAD_TILES = 13; //12?, 14?
public int ITERATIONS_TO_RUN_GC = 100;
public int NUMBER_OF_DESIRABLE_TILES_IN_MEMORY = 25;
public final RoutingConfiguration config;
private int garbageCollectorIteration = 0;
// 1.2 Dynamic road prioritizing (heuristic)
private boolean useDynamicRoadPrioritising = true;
// 1.3 Relaxing strategy
private boolean useRelaxingStrategy = true;
public int ITERATIONS_TO_RELAX_NODES = 100;
private int relaxingIteration = 0;
// 1.4 Build A* graph in backward/forward direction (can affect results)
// null - 2 ways, true - direct way, false - reverse way
private Boolean planRoadDirection = null;
// 1.5 Router specific coefficients and restrictions
private VehicleRouter router = new CarRouter();
// not used right now
private boolean usingShortestWay = false;
// 2. Routing memory cache (big objects)
TIntObjectHashMap<RoutingTile> tiles = new TIntObjectHashMap<RoutingContext.RoutingTile>();
@ -75,6 +51,10 @@ public class RoutingContext {
// callback of processing segments
RouteSegmentVisitor visitor = null;
public RoutingContext(RoutingConfiguration config) {
this.config = config;
}
public RouteSegmentVisitor getVisitor() {
return visitor;
@ -93,8 +73,8 @@ public class RoutingContext {
public boolean runTilesGC() {
garbageCollectorIteration++;
int loadedTilesCritical = NUMBER_OF_DESIRABLE_TILES_IN_MEMORY * 3 /2;
if (garbageCollectorIteration > ITERATIONS_TO_RUN_GC ||
int loadedTilesCritical = config.NUMBER_OF_DESIRABLE_TILES_IN_MEMORY * 3 /2;
if (garbageCollectorIteration > config.ITERATIONS_TO_RUN_GC ||
getCurrentlyLoadedTiles() > loadedTilesCritical) {
garbageCollectorIteration = 0;
return true;
@ -104,7 +84,7 @@ public class RoutingContext {
public boolean runRelaxingStrategy(){
relaxingIteration++;
if(relaxingIteration > ITERATIONS_TO_RELAX_NODES){
if(relaxingIteration > config.ITERATIONS_TO_RELAX_NODES){
relaxingIteration = 0;
return true;
}
@ -117,75 +97,68 @@ public class RoutingContext {
}
public boolean isUseDynamicRoadPrioritising() {
return useDynamicRoadPrioritising;
return config.useDynamicRoadPrioritising;
}
public boolean isUseRelaxingStrategy() {
return useRelaxingStrategy;
return config.useRelaxingStrategy;
}
public void setUseRelaxingStrategy(boolean useRelaxingStrategy) {
this.useRelaxingStrategy = useRelaxingStrategy;
config.useRelaxingStrategy = useRelaxingStrategy;
}
public void setUseDynamicRoadPrioritising(boolean useDynamicRoadPrioritising) {
this.useDynamicRoadPrioritising = useDynamicRoadPrioritising;
config.useDynamicRoadPrioritising = useDynamicRoadPrioritising;
}
public void setUsingShortestWay(boolean usingShortestWay) {
this.usingShortestWay = usingShortestWay;
}
public boolean isUsingShortestWay() {
return usingShortestWay;
}
public void setRouter(VehicleRouter router) {
this.router = router;
config.router = router;
}
public void setHeuristicCoefficient(double heuristicCoefficient) {
this.heuristicCoefficient = heuristicCoefficient;
config.heuristicCoefficient = heuristicCoefficient;
}
public VehicleRouter getRouter() {
return router;
return config.router;
}
public boolean planRouteIn2Directions() {
return planRoadDirection == null;
return config.planRoadDirection == 0;
}
public Boolean getPlanRoadDirection() {
return planRoadDirection;
public int getPlanRoadDirection() {
return config.planRoadDirection;
}
public void setPlanRoadDirection(Boolean planRoadDirection) {
this.planRoadDirection = planRoadDirection;
public void setPlanRoadDirection(int planRoadDirection) {
config.planRoadDirection = planRoadDirection;
}
public int roadPriorityComparator(double o1DistanceFromStart, double o1DistanceToEnd, double o2DistanceFromStart, double o2DistanceToEnd) {
return BinaryRoutePlanner.roadPriorityComparator(o1DistanceFromStart, o1DistanceToEnd, o2DistanceFromStart, o2DistanceToEnd,
heuristicCoefficient);
config.heuristicCoefficient);
}
public RoutingTile getRoutingTile(int x31, int y31){
int xloc = x31 >> (31 - ZOOM_TO_LOAD_TILES);
int yloc = y31 >> (31 - ZOOM_TO_LOAD_TILES);
int l = (xloc << ZOOM_TO_LOAD_TILES) + yloc;
int xloc = x31 >> (31 - config.ZOOM_TO_LOAD_TILES);
int yloc = y31 >> (31 - config.ZOOM_TO_LOAD_TILES);
int l = (xloc << config.ZOOM_TO_LOAD_TILES) + yloc;
RoutingTile tl = tiles.get(l);
if(tl == null) {
tl = new RoutingTile(xloc, yloc, ZOOM_TO_LOAD_TILES);
tl = new RoutingTile(xloc, yloc, config.ZOOM_TO_LOAD_TILES);
tiles.put(l, tl);
}
return tiles.get(l);
}
public void unloadTile(RoutingTile tile, boolean createEmpty){
int l = (tile.tileX << ZOOM_TO_LOAD_TILES) + tile.tileY;
int l = (tile.tileX << config.ZOOM_TO_LOAD_TILES) + tile.tileY;
RoutingTile old = tiles.remove(l);
RoutingTile n = new RoutingTile(tile.tileX, tile.tileY, ZOOM_TO_LOAD_TILES);
RoutingTile n = new RoutingTile(tile.tileX, tile.tileY, config.ZOOM_TO_LOAD_TILES);
n.isLoaded = old.isLoaded;
n.setUnloaded();
tiles.put(l, n);

View file

@ -14,6 +14,8 @@ public abstract class VehicleRouter {
* @return
*/
public abstract boolean acceptLine(RouteDataObject way);
public abstract boolean restrictionsAwayre();
public int isOneWay(RouteDataObject road) {

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8" ?>
<osmand_routing_config defaultProfile="car">
<!-- 1. parameters of routing and different tweaks Influence on A* : -->
<!-- f(x) + heuristicCoefficient*g(X) -->
<attribute name="heuristicCoefficient" value="1.0" />
<!-- 1.1 tile load parameters (should not affect routing) -->
<attribute name="zoomToLoadTiles" value="13" />
<attribute name="iterationsToRunGC" value="100" />
<attribute name="desirableTilesInMemory" value="25" />
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
<attribute name="useDynamicRoadPrioritising" value="true" />
<!-- 1.3 Relaxing strategy -->
<attribute name="useRelaxingStrategy" value="true" />
<attribute name="iterationsToRelaxRoutes" value="100" />
<attribute name="relaxNodesIfStartDistSmallCoeff" value="3.0"/>
<!-- 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" />
<routingProfile name="car" baseProfile="car" restrictionsAware="true" minDefaultSpeed="45.0" maxDefaultSpeed="110.0"
leftTurn="20.0" rightTurn="10.0" followSpeedLimitations="true" onewayAware="true">
<highway value="motorway" speed="110" priority="1.5" dynamicPriority="1.4"/>
<highway value="motorway_link" speed="80" priority="1.3" dynamicPriority="1"/>
<highway value="trunk" speed="100" priority="1.5" dynamicPriority="1.4"/>
<highway value="trunk_link" speed="90" priority="1.3" dynamicPriority="1"/>
<!-- generally linking larger towns. -->
<highway value="primary" speed="65" priority="1.3" dynamicPriority="1.2"/>
<highway value="primary_link" speed="45" priority="1.1" dynamicPriority="1"/>
<!-- generally linking smaller towns and villages -->
<highway value="secondary" speed="50" priority="1.1" dynamicPriority="1.1"/>
<highway value="secondary_link" speed="40" priority="1" dynamicPriority="1"/>
<!-- important urban roads -->
<highway value="tertiary" speed="35" priority="0.85" dynamicPriority="0.8"/>
<highway value="tertiary_link" speed="30" priority="0.85" dynamicPriority="0.8"/>
<!-- lowest form of grid network, usually 90% of urban roads -->
<highway value="unclassified" speed="30" priority="0.7" dynamicPriority="0.7"/>
<!-- road = no type, no review and may be not accurate -->
<highway value="road" speed="30" priority="0.4" dynamicPriority="0.7"/>
<!-- primarily for access to properties, small roads with 1/2 intersections -->
<highway value="residential" speed="30" priority="0.4" dynamicPriority="0.7"/>
<!-- parking + private roads -->
<highway value="service" speed="20" priority="0.5" dynamicPriority="0.7"/>
<!-- very bad roads -->
<highway value="track" speed="15" priority="0.3" dynamicPriority="0.5"/>
<!-- may not be usable by cars!! -->
<highway value="path" speed="10" priority="0.2" dynamicPriority="0.5"/>
<!-- too small for cars usually -->
<highway value="living_street" speed="10" priority="0.1" dynamicPriority="0.5"/>
<!-- car are able to enter in highway=pedestrian with restrictions -->
<obstacle tag="highway" value="traffic_signals" penalty="35"/>
<obstacle tag="railway" value="crossing" penalty="25"/>
<obstacle tag="railway" value="level_crossing" penalty="25"/>
</routingProfile>
<routingProfile name="bicycle" baseProfile="bicycle" restrictionsAware="true" minDefaultSpeed="7" maxDefaultSpeed="21"
leftTurn="15" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
<highway value="motorway" speed="21" priority="0.7" dynamicPriority="0.7"/>
<highway value="motorway_link" speed="21" priority="0.7" dynamicPriority="0.7"/>
<highway value="trunk" speed="21" priority="0.7" dynamicPriority="0.7"/>
<highway value="trunk_link" speed="21" priority="0.7" dynamicPriority="0.7"/>
<highway value="primary" speed="21" priority="0.9" dynamicPriority="0.9"/>
<highway value="primary_link" speed="21" priority="0.9" dynamicPriority="0.9"/>
<highway value="secondary" speed="21" priority="1" dynamicPriority="1"/>
<highway value="secondary_link" speed="21" priority="1" dynamicPriority="1"/>
<highway value="tertiary" speed="21" priority="1" dynamicPriority="1"/>
<highway value="tertiary_link" speed="21" priority="1" dynamicPriority="1"/>
<highway value="road" speed="21" priority="1" dynamicPriority="1"/>
<highway value="residential" speed="21" priority="1" dynamicPriority="1"/>
<highway value="cycleway" speed="21" priority="1" dynamicPriority="1"/>
<highway value="unclassified" speed="15" priority="1" dynamicPriority="1"/>
<highway value="service" speed="15" priority="1" dynamicPriority="1"/>
<highway value="track" speed="10" priority="0.9" dynamicPriority="0.9"/>
<highway value="path" speed="10" priority="0.9" dynamicPriority="0.9"/>
<highway value="living_street" speed="15" priority="1" dynamicPriority="1"/>
<highway value="pedestrian" speed="10" priority="0.9" dynamicPriority="0.9"/>
<highway value="footway" speed="8" priority="0.9" dynamicPriority="0.9"/>
<highway value="byway" speed="8" priority="1" dynamicPriority="1"/>
<highway value="services" speed="15" priority="1" dynamicPriority="1"/>
<highway value="bridleway" speed="8" priority="0.8" dynamicPriority="0.8"/>
<highway value="steps" speed="3" priority="0.5" dynamicPriority="0.5"/>
<obstacle tag="highway" value="traffic_signals" penalty="30"/>
<obstacle tag="railway" value="crossing" penalty="15"/>
<obstacle tag="railway" value="level_crossing" penalty="15"/>
</routingProfile>
<routingProfile name="pedestrian" baseProfile="pedestrian" restrictionsAware="false" minDefaultSpeed="3" maxDefaultSpeed="6"
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="false">
<highway value="motorway" speed="5" priority="0.7" dynamicPriority="0.7"/>
<highway value="motorway_link" speed="5" priority="0.7" dynamicPriority="0.7"/>
<highway value="trunk" speed="5" priority="0.7" dynamicPriority="0.7"/>
<highway value="trunk_link" speed="5" priority="0.7" dynamicPriority="0.7"/>
<highway value="primary" speed="6" priority="0.9" dynamicPriority="0.9"/>
<highway value="primary_link" speed="6" priority="0.9" dynamicPriority="0.9"/>
<highway value="secondary" speed="6" priority="1" dynamicPriority="1"/>
<highway value="secondary_link" speed="6" priority="1" dynamicPriority="1"/>
<highway value="tertiary" speed="6" priority="1" dynamicPriority="1"/>
<highway value="tertiary_link" speed="6" priority="1" dynamicPriority="1"/>
<highway value="road" speed="6" priority="1" dynamicPriority="1"/>
<highway value="residential" speed="6" priority="1" dynamicPriority="1"/>
<highway value="cycleway" speed="5" priority="1" dynamicPriority="1"/>
<highway value="unclassified" speed="6" priority="1" dynamicPriority="1"/>
<highway value="service" speed="6" priority="1" dynamicPriority="1"/>
<highway value="track" speed="6" priority="1" dynamicPriority="1"/>
<highway value="path" speed="6" priority="1" dynamicPriority="1"/>
<highway value="living_street" speed="6" priority="1" dynamicPriority="1"/>
<highway value="pedestrian" speed="6" priority="1.4" dynamicPriority="1.4"/>
<highway value="footway" speed="6" priority="1.4" dynamicPriority="1.4"/>
<highway value="byway" speed="6" priority="1" dynamicPriority="1"/>
<highway value="services" speed="5" priority="1" dynamicPriority="1"/>
<highway value="bridleway" speed="6" priority="0.8" dynamicPriority="0.8"/>
<highway value="steps" speed="4" priority="1.2" dynamicPriority="1"/>
<obstacle tag="highway" value="traffic_signals" penalty="30"/>
<obstacle tag="railway" value="crossing" penalty="15"/>
<obstacle tag="railway" value="level_crossing" penalty="15"/>
</routingProfile>
</osmand_routing_config>

View file

@ -11,11 +11,9 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.router.BicycleRouter;
import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.CarRouter;
import net.osmand.router.PedestrianRouter;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingContext;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.swing.NativeSwingRendering;
@ -80,8 +78,8 @@ public class RouterTestsSuite {
private static void testRoute(Element testCase, BinaryMapIndexReader[] regions) throws IOException {
BinaryRoutePlanner planner = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), regions);
RoutingContext ctx = new RoutingContext();
String vehicle = testCase.getAttribute("vehicle");
RoutingContext ctx = new RoutingContext(RoutingConfiguration.getDefault().initConfig(vehicle, true));
String testDescription = testCase.getAttribute("description");
String skip = testCase.getAttribute("skip_comment");
if (skip != null && skip.length() > 0) {
@ -89,13 +87,6 @@ public class RouterTestsSuite {
return;
}
if("bicycle".equals(vehicle)){
ctx.setRouter(new BicycleRouter());
} else if("pedestrian".equals(vehicle)){
ctx.setRouter(new PedestrianRouter());
} else {
ctx.setRouter(new CarRouter());
}
double startLat = Double.parseDouble(testCase.getAttribute("start_lat"));
double startLon = Double.parseDouble(testCase.getAttribute("start_lon"));
RouteSegment startSegment = planner.findRouteSegment(startLat, startLon, ctx);

View file

@ -194,6 +194,14 @@ public class DataExtractionSettings {
preferences.put("renderXmlPath", file);
}
public String getRoutingXmlPath(){
return preferences.get("routingXmlPath", "routing.xml");
}
public void setRoutingXmlPath(String file){
preferences.put("routingXmlPath", file);
}
public String getBinaryFilesDir(){

View file

@ -132,7 +132,7 @@ public class MapClusterLayer implements MapPanelLayer {
}
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
RoutingContext ctx = new RoutingContext();
RoutingContext ctx = new RoutingContext(null);
// find closest way
RouteSegment st = router.findRouteSegment(lat, lon, ctx);

View file

@ -8,6 +8,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
@ -36,11 +37,10 @@ import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.osm.Way;
import net.osmand.osm.OSMSettings.OSMTagKey;
import net.osmand.router.BicycleRouter;
import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.CarRouter;
import net.osmand.router.PedestrianRouter;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
@ -57,6 +57,8 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import sun.awt.image.FileImageSource;
public class MapRouterLayer implements MapPanelLayer {
@ -163,6 +165,30 @@ public class MapRouterLayer implements MapPanelLayer {
}
};
menu.add(end);
Action selfRoute = new AbstractAction("Calculate OsmAnd route") {
private static final long serialVersionUID = 507156107455281238L;
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
List<Way> ways = selfRoute(startRoute, endRoute);
if (ways != null) {
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
}
map.setPoints(points);
}
}
}.start();
}
};
menu.add(selfRoute);
Action route_YOURS = new AbstractAction("Calculate YOURS route") {
private static final long serialVersionUID = 507156107455281238L;
@ -205,51 +231,6 @@ public class MapRouterLayer implements MapPanelLayer {
}
};
menu.add(route_CloudMate);
Action route_OSRM = new AbstractAction("Calculate OSRM route") {
private static final long serialVersionUID = 2292361745482584520L;
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
List<Way> ways = route_OSRM(startRoute, endRoute);
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
}
map.setPoints(points);
}
}.start();
}
};
menu.add(route_OSRM);
Action selfRoute = new AbstractAction("Calculate OsmAnd route") {
private static final long serialVersionUID = 507156107455281238L;
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
List<Way> ways = selfRoute(startRoute, endRoute);
if (ways != null) {
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
}
map.setPoints(points);
}
}
}.start();
}
};
menu.add(selfRoute);
}
@ -536,6 +517,19 @@ public class MapRouterLayer implements MapPanelLayer {
files.add(f);
}
}
String xmlPath = DataExtractionSettings.getSettings().getRoutingXmlPath();
Builder builder;
if(xmlPath.equals("routing.xml")){
builder = RoutingConfiguration.getDefault() ;
} else{
try {
builder = RoutingConfiguration.parseFromInputStream(new FileInputStream(xmlPath));
} catch (IOException e) {
throw new IllegalArgumentException("Error parsing routing.xml file",e);
} catch (SAXException e) {
throw new IllegalArgumentException("Error parsing routing.xml file",e);
}
}
final boolean animateRoutingCalculation = DataExtractionSettings.getSettings().isAnimateRouting();
if(animateRoutingCalculation) {
nextTurn.setVisible(true);
@ -559,24 +553,14 @@ public class MapRouterLayer implements MapPanelLayer {
RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$ //$NON-NLS-2$
rs[it++] = new BinaryMapIndexReader(raf, false);
}
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
RoutingContext ctx = new RoutingContext();
String m = DataExtractionSettings.getSettings().getRouteMode();
if("pedestrian".equalsIgnoreCase(m)) {
ctx.setRouter(new PedestrianRouter());
log.info("Use pedestrian mode for routing");
} else if("pedestrian".equalsIgnoreCase(m)) {
ctx.setRouter(new BicycleRouter());
log.info("Use bicycle mode for routing");
} else {
ctx.setRouter(new CarRouter());
log.info("Use car mode for routing");
}
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
RoutingConfiguration config = builder.initConfig(m, true);
RoutingContext ctx = new RoutingContext(config);
log.info("Use " + config.routerName + "mode for routing");
int dir = DataExtractionSettings.getSettings().getRouteDirection();
if(dir != 0) {
ctx.setPlanRoadDirection(dir > 0 ? true : false);
}
ctx.setPlanRoadDirection(dir);
// find closest way
RouteSegment st = router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);

View file

@ -33,12 +33,11 @@ public class OsmExtractionPreferencesDialog extends JDialog {
private JTextField directionPlanRoute;
private JTextField routingMode;
private JTextField lineSmoothness;
private JTextField cityAdminLevel;
private JTextField osrmServerAddress;
private JTextField renderingTypesFile;
private JTextField nativeLibFile;
private JTextField nativeFilesDirectory;
private JTextField renderingStyleFile;
private JTextField routingConfigFile;
private JCheckBox useInternet;
private JCheckBox animateRouting;
@ -163,7 +162,7 @@ public class OsmExtractionPreferencesDialog extends JDialog {
constr.gridy = gridY++;
l.setConstraints(routingMode, constr);
label = new JLabel("Direction to plan route (0 - both, 1 - forward, -1 - backward) : ");
label = new JLabel("Direction to plan route (1/0/-1 forw/both/back) :");
panel.add(label);
constr = new GridBagConstraints();
constr.ipadx = 5;
@ -183,9 +182,8 @@ public class OsmExtractionPreferencesDialog extends JDialog {
constr.gridx = 1;
constr.gridy = gridY++;
l.setConstraints(directionPlanRoute, constr);
label = new JLabel("City admin level : ");
label = new JLabel("Routing config file (path : ");
panel.add(label);
constr = new GridBagConstraints();
constr.ipadx = 5;
@ -194,40 +192,19 @@ public class OsmExtractionPreferencesDialog extends JDialog {
constr.anchor = GridBagConstraints.WEST;
l.setConstraints(label, constr);
cityAdminLevel = new JTextField();
cityAdminLevel.setText(DataExtractionSettings.getSettings().getCityAdminLevel());
panel.add(cityAdminLevel);
routingConfigFile = new JTextField();
routingConfigFile.setText(DataExtractionSettings.getSettings().getRoutingXmlPath());
panel.add(routingConfigFile);
constr = new GridBagConstraints();
constr.weightx = 1;
constr.fill = GridBagConstraints.HORIZONTAL;
constr.ipadx = 5;
constr.gridx = 1;
constr.gridy = gridY++;
l.setConstraints(cityAdminLevel, constr);
l.setConstraints(routingConfigFile, constr);
label = new JLabel(Messages.getString("OsmExtractionPreferencesDialog.OSRM.SERVER.ADDRESS"));
panel.add(label);
constr = new GridBagConstraints();
constr.ipadx = 5;
constr.gridx = 0;
constr.gridy = gridY;
constr.anchor = GridBagConstraints.WEST;
l.setConstraints(label, constr);
osrmServerAddress = new JTextField();
osrmServerAddress.setText(DataExtractionSettings.getSettings().getOsrmServerAddress());
panel.add(osrmServerAddress);
constr = new GridBagConstraints();
constr.weightx = 1;
constr.fill = GridBagConstraints.HORIZONTAL;
constr.ipadx = 5;
constr.gridx = 1;
constr.gridy = gridY++;
l.setConstraints(osrmServerAddress, constr);
label = new JLabel("Rendering style file : ");
label = new JLabel("Rendering style file (path) : ");
panel.add(label);
constr = new GridBagConstraints();
constr.ipadx = 5;
@ -267,16 +244,6 @@ public class OsmExtractionPreferencesDialog extends JDialog {
constr.gridy = gridY++;
l.setConstraints(nativeLibFile, constr);
// supressWarning = new JCheckBox();
// supressWarning.setText(Messages.getString("OsmExtractionPreferencesDialog.DUPLICATED.ID")); //$NON-NLS-1$
// supressWarning.setSelected(DataExtractionSettings.getSettings().isSupressWarningsForDuplicatedId());
// panel.add(supressWarning);
//
// loadWholeOsmInfo = new JCheckBox();
// loadWholeOsmInfo.setText(Messages.getString("OsmExtractionPreferencesDialog.LOAD.WHOLE.OSM")); //$NON-NLS-1$
// loadWholeOsmInfo.setSelected(DataExtractionSettings.getSettings().getLoadEntityInfo());
// panel.add(loadWholeOsmInfo);
panel.setMaximumSize(new Dimension(Short.MAX_VALUE, panel.getPreferredSize().height));
}
@ -437,9 +404,6 @@ public class OsmExtractionPreferencesDialog extends JDialog {
if(!settings.getMapRenderingTypesFile().equals(renderingTypesFile.getText())){
settings.setMapRenderingTypesFile(renderingTypesFile.getText());
}
if(!settings.getCityAdminLevel().equals(cityAdminLevel.getText())){
settings.setCityAdminLevel(cityAdminLevel.getText());
}
int directionRoute = 0;
try {
directionRoute = Integer.parseInt(directionPlanRoute.getText());
@ -447,9 +411,6 @@ public class OsmExtractionPreferencesDialog extends JDialog {
}
if(directionRoute != settings.getRouteDirection()){
settings.setRouteDirection(directionRoute);
}
if(!settings.getOsrmServerAddress().equals(osrmServerAddress.getText())){
settings.setOsrmServerAddress(osrmServerAddress.getText());
}
if(!settings.getBinaryFilesDir().equals(nativeFilesDirectory.getText())){
settings.setBinaryFilesDir(nativeFilesDirectory.getText());
@ -458,17 +419,13 @@ public class OsmExtractionPreferencesDialog extends JDialog {
if(!settings.getRenderXmlPath().equals(renderingStyleFile.getText())){
settings.setRenderXmlPath(renderingStyleFile.getText());
}
if(!settings.getRoutingXmlPath().equals(routingConfigFile.getText())){
settings.setRoutingXmlPath(routingConfigFile.getText());
}
if(!settings.getRouteMode().equals(routingMode.getText())){
settings.setRouteMode(routingMode.getText());
}
// if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){
// settings.setSupressWarningsForDuplicatedId (supressWarning.isSelected());
// }
// if(settings.getLoadEntityInfo() != loadWholeOsmInfo.isSelected()){
// settings.setLoadEntityInfo(loadWholeOsmInfo.isSelected());
// }
}

View file

@ -34,12 +34,11 @@ import net.osmand.plus.activities.ApplicationMode;
import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RoutingHelper.RouteDirectionInfo;
import net.osmand.plus.routing.RoutingHelper.TurnType;
import net.osmand.router.BicycleRouter;
import net.osmand.router.BinaryRoutePlanner;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
import net.osmand.router.CarRouter;
import net.osmand.router.PedestrianRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.RouteSegmentResult;
import net.osmand.router.RoutingConfiguration;
import net.osmand.router.RoutingContext;
import org.w3c.dom.Document;
@ -655,20 +654,16 @@ public class RouteProvider {
protected RouteCalculationResult findVectorMapsRoute(Location start, LatLon end, ApplicationMode mode, boolean fast, OsmandApplication app) throws IOException {
BinaryMapIndexReader[] files = app.getResourceManager().getRoutingMapFiles();
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeOsmandLibrary.getLoadedLibrary(), files);
RoutingContext ctx = new RoutingContext();
ctx.setUsingShortestWay(!fast);
//ctx.setPlanRoadDirection(null);
RoutingConfiguration.Builder config = RoutingConfiguration.getDefault();
GeneralRouterProfile p ;
if (mode == ApplicationMode.BICYCLE) {
ctx.setRouter(new BicycleRouter());
ctx.setUseDynamicRoadPrioritising(true);
p = GeneralRouterProfile.BICYCLE;
} else if (mode == ApplicationMode.PEDESTRIAN) {
ctx.setRouter(new PedestrianRouter());
ctx.setUseDynamicRoadPrioritising(false);
ctx.setHeuristicCoefficient(2);
p = GeneralRouterProfile.PEDESTRIAN;
} else {
ctx.setRouter(new CarRouter());
ctx.setUseDynamicRoadPrioritising(true);
p = GeneralRouterProfile.CAR;
}
RoutingContext ctx = new RoutingContext(config.initConfig(p.name().toLowerCase(), !fast));
RouteSegment st= router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx);
if (st == null) {
return new RouteCalculationResult("Starting point too far from nearest road.");