Update routing and add parameters to configuration
This commit is contained in:
parent
00eded8171
commit
a607b5c636
4 changed files with 119 additions and 40 deletions
|
@ -90,7 +90,8 @@ public class GeneralRouter implements VehicleRouter {
|
|||
CAR,
|
||||
PEDESTRIAN,
|
||||
BICYCLE,
|
||||
BOAT
|
||||
BOAT,
|
||||
PUBLIC_TRANSPORT
|
||||
}
|
||||
|
||||
|
||||
|
@ -224,7 +225,7 @@ public class GeneralRouter implements VehicleRouter {
|
|||
return impassableRoads.toArray();
|
||||
}
|
||||
|
||||
private int registerTagValueAttribute(String tag, String value) {
|
||||
public int registerTagValueAttribute(String tag, String value) {
|
||||
String key = tag +"$"+value;
|
||||
if(universalRules.containsKey(key)) {
|
||||
return universalRules.get(key);
|
||||
|
@ -617,6 +618,14 @@ public class GeneralRouter implements VehicleRouter {
|
|||
return ((Number)o).intValue();
|
||||
}
|
||||
|
||||
public int evaluateInt(BitSet rawTypes, int defValue) {
|
||||
Object o = evaluate(rawTypes);
|
||||
if(!(o instanceof Number)){
|
||||
return defValue;
|
||||
}
|
||||
return ((Number)o).intValue();
|
||||
}
|
||||
|
||||
public float evaluateFloat(RouteDataObject ro, float defValue) {
|
||||
Object o = evaluate(ro);
|
||||
if(!(o instanceof Number)) {
|
||||
|
@ -633,6 +642,14 @@ public class GeneralRouter implements VehicleRouter {
|
|||
return ((Number)o).floatValue();
|
||||
}
|
||||
|
||||
public float evaluateFloat(BitSet rawTypes, float defValue) {
|
||||
Object o = evaluate(rawTypes);
|
||||
if(!(o instanceof Number)){
|
||||
return defValue;
|
||||
}
|
||||
return ((Number)o).floatValue();
|
||||
}
|
||||
|
||||
private BitSet convert(RouteRegion reg, int[] types) {
|
||||
BitSet b = new BitSet(universalRules.size());
|
||||
Map<Integer, Integer> map = regionConvert.get(reg);
|
||||
|
|
|
@ -136,7 +136,7 @@ public class RoutingConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private static int parseSilentInt(String t, int v) {
|
||||
public static int parseSilentInt(String t, int v) {
|
||||
if (t == null || t.length() == 0) {
|
||||
return v;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ public class RoutingConfiguration {
|
|||
}
|
||||
|
||||
|
||||
private static float parseSilentFloat(String t, float v) {
|
||||
public static float parseSilentFloat(String t, float v) {
|
||||
if (t == null || t.length() == 0) {
|
||||
return v;
|
||||
}
|
||||
|
@ -217,8 +217,8 @@ public class RoutingConfiguration {
|
|||
String valueDescriptions = parser.getAttributeValue("", "valueDescriptions");
|
||||
String[] strValues = values.split(",");
|
||||
Double[] vls = new Double[strValues.length];
|
||||
for(int i =0; i< vls.length; i++) {
|
||||
vls[i] =Double.parseDouble(strValues[i].trim());
|
||||
for (int i = 0; i < vls.length; i++) {
|
||||
vls[i] = Double.parseDouble(strValues[i].trim());
|
||||
}
|
||||
currentRouter.registerNumericParameter(id, name, description, vls ,
|
||||
valueDescriptions.split(","));
|
||||
|
|
|
@ -79,6 +79,10 @@ public class TransportRoutePlanner {
|
|||
double minDist = 0;
|
||||
double travelDist = 0;
|
||||
double travelTime = 0;
|
||||
final float routeTravelSpeed = ctx.cfg.getSpeedByRouteType(segment.road.getType());
|
||||
if(routeTravelSpeed == 0) {
|
||||
continue;
|
||||
}
|
||||
TransportStop prevStop = segment.getStop(segment.segStart);
|
||||
List<TransportRouteSegment> sgms = new ArrayList<TransportRouteSegment>();
|
||||
for (int ind = 1 + segment.segStart; ind < segment.getLength(); ind++) {
|
||||
|
@ -96,7 +100,7 @@ public class TransportRoutePlanner {
|
|||
int interval = sc.avgStopIntervals.get(ind - 1);
|
||||
travelTime += interval * 10;
|
||||
} else {
|
||||
travelTime += ctx.cfg.stopTime + segmentDist / ctx.cfg.travelSpeed;
|
||||
travelTime += ctx.cfg.stopTime + segmentDist / routeTravelSpeed;
|
||||
}
|
||||
if(segment.distFromStart + travelTime > finishTime + ctx.cfg.finishTimeSeconds) {
|
||||
break;
|
||||
|
@ -118,7 +122,7 @@ public class TransportRoutePlanner {
|
|||
nextSegment.parentTravelTime = travelTime;
|
||||
nextSegment.parentTravelDist = travelDist;
|
||||
double walkTime = nextSegment.walkDist / ctx.cfg.walkSpeed
|
||||
+ (ctx.cfg.getChangeTime());
|
||||
+ ctx.cfg.getChangeTime() + ctx.cfg.getBoardingTime();
|
||||
nextSegment.distFromStart = segment.distFromStart + travelTime + walkTime;
|
||||
if(ctx.cfg.useSchedule) {
|
||||
int tm = (sgm.departureTime - ctx.cfg.scheduleTimeOfDay) * 10;
|
||||
|
@ -181,7 +185,7 @@ public class TransportRoutePlanner {
|
|||
ctx.calculationProgress.distanceFromEnd = 0;
|
||||
ctx.calculationProgress.reverseSegmentQueueSize = 0;
|
||||
ctx.calculationProgress.directSegmentQueueSize = 0;
|
||||
float speed = (float) ctx.cfg.travelSpeed + 1; // assume
|
||||
float speed = (float) ctx.cfg.defaultTravelSpeed + 1; // assume
|
||||
ctx.calculationProgress.totalEstimatedDistance = (float) (MapUtils.getDistance(start, end) / speed);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +230,7 @@ public class TransportRoutePlanner {
|
|||
sg.walkDist = p.parentRoute.walkDist;
|
||||
sg.walkTime = sg.walkDist / ctx.cfg.walkSpeed;
|
||||
sg.depTime = p.departureTime;
|
||||
sg.travelInaccurateDist = p.parentTravelDist;
|
||||
sg.travelDistApproximate = p.parentTravelDist;
|
||||
sg.travelTime = p.parentTravelTime;
|
||||
route.segments.add(0, sg);
|
||||
}
|
||||
|
@ -294,7 +298,7 @@ public class TransportRoutePlanner {
|
|||
private static final int DISPLAY_SEGMENT_IND = 0;
|
||||
public TransportRoute route;
|
||||
public double walkTime;
|
||||
public double travelInaccurateDist;
|
||||
public double travelDistApproximate;
|
||||
public double travelTime;
|
||||
public int start;
|
||||
public int end;
|
||||
|
@ -322,6 +326,10 @@ public class TransportRoutePlanner {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public double getTravelTime() {
|
||||
return travelTime;
|
||||
}
|
||||
|
||||
public TransportStop getStart() {
|
||||
return route.getForwardStops().get(start);
|
||||
}
|
||||
|
@ -478,18 +486,21 @@ public class TransportRoutePlanner {
|
|||
}
|
||||
|
||||
public double getTravelTime() {
|
||||
if(cfg.useSchedule) {
|
||||
int t = 0;
|
||||
for(TransportRouteResultSegment s : segments) {
|
||||
double t = 0;
|
||||
for (TransportRouteResultSegment s : segments) {
|
||||
if (cfg.useSchedule) {
|
||||
TransportSchedule sts = s.route.getSchedule();
|
||||
for (int k = s.start; k < s.end; k++) {
|
||||
t += sts.getAvgStopIntervals()[k] * 10;
|
||||
}
|
||||
} else {
|
||||
if (t > 0) {
|
||||
t += cfg.getBoardingTime();
|
||||
}
|
||||
t += s.getTravelTime();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
return getTravelDist() / cfg.travelSpeed + cfg.stopTime * getStops() +
|
||||
cfg.getChangeTime() * getChanges();
|
||||
return t;
|
||||
}
|
||||
|
||||
public double getWalkTime() {
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.osmand.router.GeneralRouter.RouteAttributeContext;
|
||||
import net.osmand.router.GeneralRouter.RouteDataObjectAttribute;
|
||||
|
||||
public class TransportRoutingConfiguration {
|
||||
|
||||
public static final String KEY = "public_transport";
|
||||
|
@ -10,52 +19,94 @@ public class TransportRoutingConfiguration {
|
|||
|
||||
public int walkChangeRadius = 300;
|
||||
|
||||
public double walkSpeed = 3.6 / 3.6; // m/s
|
||||
|
||||
public double travelSpeed = 36 / 3.6; // m/s
|
||||
|
||||
public int stopTime = 30;
|
||||
|
||||
public int changeTime = 300;
|
||||
|
||||
public int maxNumberOfChanges = 5;
|
||||
public int maxNumberOfChanges = 4;
|
||||
|
||||
public int finishTimeSeconds = 1200;
|
||||
|
||||
public int maxRouteTime = 60 * 60 * 10; // 10 hours
|
||||
|
||||
public boolean useSchedule;
|
||||
public GeneralRouter router;
|
||||
// cache values from router for fast access
|
||||
public float walkSpeed = (float) (3.6 / 3.6); // m/s
|
||||
public float defaultTravelSpeed = (float) (60 / 3.6); // m/s
|
||||
public int stopTime = 30;
|
||||
public int changeTime = 180;
|
||||
public int boardingTime = 180;
|
||||
|
||||
public boolean useSchedule;
|
||||
// 10 seconds based
|
||||
public int scheduleTimeOfDay = 12 * 60 * 6; // 12:00 - 60*6*12
|
||||
|
||||
public int scheduleMaxTime = 50 * 6; // TODO not appropriate variable, should be dynamic
|
||||
|
||||
public int scheduleMinChangeTime = 180; // 3 min
|
||||
|
||||
// day since 2000
|
||||
public int scheduleDayNumber;
|
||||
|
||||
private Map<String, Integer> rawTypes = new HashMap<String, Integer>();
|
||||
private Map<String, Float> speed = new TreeMap<String, Float>();
|
||||
|
||||
|
||||
public float getSpeedByRouteType(String routeType) {
|
||||
Float sl = speed.get(routeType);
|
||||
if(sl == null) {
|
||||
RouteAttributeContext spds = router.getObjContext(RouteDataObjectAttribute.ROAD_SPEED);
|
||||
sl = spds.evaluateFloat(getRawBitset("route", routeType), defaultTravelSpeed);
|
||||
speed.put(routeType, sl);
|
||||
}
|
||||
return sl.floatValue();
|
||||
}
|
||||
|
||||
private int getRawType(String tg, String vl) {
|
||||
String key = tg + "$"+vl;
|
||||
if(!rawTypes.containsKey(key)) {
|
||||
int at = router.registerTagValueAttribute(tg, vl);
|
||||
rawTypes.put(key, at);
|
||||
}
|
||||
return rawTypes.get(key);
|
||||
}
|
||||
|
||||
private BitSet getRawBitset(String tg, String vl) {
|
||||
BitSet bs = new BitSet();
|
||||
bs.set(getRawType(tg, vl));
|
||||
return bs;
|
||||
}
|
||||
|
||||
|
||||
public int getChangeTime() {
|
||||
return useSchedule ? scheduleMinChangeTime : changeTime;
|
||||
return useSchedule ? 0 : changeTime;
|
||||
}
|
||||
|
||||
public int getBoardingTime() {
|
||||
return boardingTime;
|
||||
}
|
||||
|
||||
public TransportRoutingConfiguration(RoutingConfiguration.Builder builder) {
|
||||
GeneralRouter router = builder == null ? null : builder.getRouter("public_transport");
|
||||
if(router != null) {
|
||||
this(builder, Collections.emptyMap());
|
||||
}
|
||||
|
||||
public TransportRoutingConfiguration(RoutingConfiguration.Builder builder, Map<String, String> params) {
|
||||
GeneralRouter prouter = builder == null ? null : builder.getRouter("public_transport");
|
||||
if(prouter != null) {
|
||||
this.router = prouter.build(params);
|
||||
walkRadius = router.getIntAttribute("walkRadius", walkRadius);
|
||||
walkChangeRadius = router.getIntAttribute("walkChangeRadius", walkRadius);
|
||||
walkChangeRadius = router.getIntAttribute("walkChangeRadius", walkChangeRadius);
|
||||
ZOOM_TO_LOAD_TILES = router.getIntAttribute("zoomToLoadTiles", ZOOM_TO_LOAD_TILES);
|
||||
maxNumberOfChanges = router.getIntAttribute("maxNumberOfChanges", maxNumberOfChanges);
|
||||
maxRouteTime = router.getIntAttribute("maxRouteTime", maxRouteTime);
|
||||
finishTimeSeconds = router.getIntAttribute("delayForAlternativesRoutes", finishTimeSeconds);
|
||||
String mn = params.get("max_num_changes");
|
||||
maxNumberOfChanges = RoutingConfiguration.parseSilentInt(mn, maxNumberOfChanges);
|
||||
|
||||
walkSpeed = router.getFloatAttribute("minDefaultSpeed", this.walkSpeed * 3.6f) / 3.6f;
|
||||
defaultTravelSpeed = router.getFloatAttribute("maxDefaultSpeed", this.defaultTravelSpeed * 3.6f) / 3.6f;
|
||||
|
||||
RouteAttributeContext obstacles = router.getObjContext(RouteDataObjectAttribute.ROUTING_OBSTACLES);
|
||||
stopTime = obstacles.evaluateInt(getRawBitset("time", "stop"), stopTime);
|
||||
changeTime = obstacles.evaluateInt(getRawBitset("time", "change"), changeTime);
|
||||
boardingTime = obstacles.evaluateInt(getRawBitset("time", "boarding"), boardingTime);
|
||||
|
||||
RouteAttributeContext spds = router.getObjContext(RouteDataObjectAttribute.ROAD_SPEED);
|
||||
walkSpeed = spds.evaluateFloat(getRawBitset("route", "walk"), walkSpeed);
|
||||
|
||||
|
||||
travelSpeed = router.getFloatAttribute("defaultTravelSpeed", (float) travelSpeed);
|
||||
walkSpeed = router.getFloatAttribute("defaultWalkSpeed", (float) walkSpeed);
|
||||
stopTime = router.getIntAttribute("defaultStopTime", stopTime);
|
||||
changeTime = router.getIntAttribute("defaultChangeTime", changeTime);
|
||||
scheduleMinChangeTime = router.getIntAttribute("defaultScheduleChangeTime", changeTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue