Merge branch 'r3.3'

This commit is contained in:
Victor Shcherb 2019-03-17 14:10:04 +01:00
commit 8617ef668b
4 changed files with 119 additions and 40 deletions

View file

@ -90,7 +90,8 @@ public class GeneralRouter implements VehicleRouter {
CAR, CAR,
PEDESTRIAN, PEDESTRIAN,
BICYCLE, BICYCLE,
BOAT BOAT,
PUBLIC_TRANSPORT
} }
@ -224,7 +225,7 @@ public class GeneralRouter implements VehicleRouter {
return impassableRoads.toArray(); return impassableRoads.toArray();
} }
private int registerTagValueAttribute(String tag, String value) { public int registerTagValueAttribute(String tag, String value) {
String key = tag +"$"+value; String key = tag +"$"+value;
if(universalRules.containsKey(key)) { if(universalRules.containsKey(key)) {
return universalRules.get(key); return universalRules.get(key);
@ -617,6 +618,14 @@ public class GeneralRouter implements VehicleRouter {
return ((Number)o).intValue(); 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) { public float evaluateFloat(RouteDataObject ro, float defValue) {
Object o = evaluate(ro); Object o = evaluate(ro);
if(!(o instanceof Number)) { if(!(o instanceof Number)) {
@ -633,6 +642,14 @@ public class GeneralRouter implements VehicleRouter {
return ((Number)o).floatValue(); 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) { private BitSet convert(RouteRegion reg, int[] types) {
BitSet b = new BitSet(universalRules.size()); BitSet b = new BitSet(universalRules.size());
Map<Integer, Integer> map = regionConvert.get(reg); Map<Integer, Integer> map = regionConvert.get(reg);

View file

@ -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) { if (t == null || t.length() == 0) {
return v; 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) { if (t == null || t.length() == 0) {
return v; return v;
} }
@ -217,8 +217,8 @@ public class RoutingConfiguration {
String valueDescriptions = parser.getAttributeValue("", "valueDescriptions"); String valueDescriptions = parser.getAttributeValue("", "valueDescriptions");
String[] strValues = values.split(","); String[] strValues = values.split(",");
Double[] vls = new Double[strValues.length]; Double[] vls = new Double[strValues.length];
for(int i =0; i< vls.length; i++) { for (int i = 0; i < vls.length; i++) {
vls[i] =Double.parseDouble(strValues[i].trim()); vls[i] = Double.parseDouble(strValues[i].trim());
} }
currentRouter.registerNumericParameter(id, name, description, vls , currentRouter.registerNumericParameter(id, name, description, vls ,
valueDescriptions.split(",")); valueDescriptions.split(","));

View file

@ -79,6 +79,10 @@ public class TransportRoutePlanner {
double minDist = 0; double minDist = 0;
double travelDist = 0; double travelDist = 0;
double travelTime = 0; double travelTime = 0;
final float routeTravelSpeed = ctx.cfg.getSpeedByRouteType(segment.road.getType());
if(routeTravelSpeed == 0) {
continue;
}
TransportStop prevStop = segment.getStop(segment.segStart); TransportStop prevStop = segment.getStop(segment.segStart);
List<TransportRouteSegment> sgms = new ArrayList<TransportRouteSegment>(); List<TransportRouteSegment> sgms = new ArrayList<TransportRouteSegment>();
for (int ind = 1 + segment.segStart; ind < segment.getLength(); ind++) { for (int ind = 1 + segment.segStart; ind < segment.getLength(); ind++) {
@ -96,7 +100,7 @@ public class TransportRoutePlanner {
int interval = sc.avgStopIntervals.get(ind - 1); int interval = sc.avgStopIntervals.get(ind - 1);
travelTime += interval * 10; travelTime += interval * 10;
} else { } else {
travelTime += ctx.cfg.stopTime + segmentDist / ctx.cfg.travelSpeed; travelTime += ctx.cfg.stopTime + segmentDist / routeTravelSpeed;
} }
if(segment.distFromStart + travelTime > finishTime + ctx.cfg.finishTimeSeconds) { if(segment.distFromStart + travelTime > finishTime + ctx.cfg.finishTimeSeconds) {
break; break;
@ -118,7 +122,7 @@ public class TransportRoutePlanner {
nextSegment.parentTravelTime = travelTime; nextSegment.parentTravelTime = travelTime;
nextSegment.parentTravelDist = travelDist; nextSegment.parentTravelDist = travelDist;
double walkTime = nextSegment.walkDist / ctx.cfg.walkSpeed double walkTime = nextSegment.walkDist / ctx.cfg.walkSpeed
+ (ctx.cfg.getChangeTime()); + ctx.cfg.getChangeTime() + ctx.cfg.getBoardingTime();
nextSegment.distFromStart = segment.distFromStart + travelTime + walkTime; nextSegment.distFromStart = segment.distFromStart + travelTime + walkTime;
if(ctx.cfg.useSchedule) { if(ctx.cfg.useSchedule) {
int tm = (sgm.departureTime - ctx.cfg.scheduleTimeOfDay) * 10; int tm = (sgm.departureTime - ctx.cfg.scheduleTimeOfDay) * 10;
@ -181,7 +185,7 @@ public class TransportRoutePlanner {
ctx.calculationProgress.distanceFromEnd = 0; ctx.calculationProgress.distanceFromEnd = 0;
ctx.calculationProgress.reverseSegmentQueueSize = 0; ctx.calculationProgress.reverseSegmentQueueSize = 0;
ctx.calculationProgress.directSegmentQueueSize = 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); ctx.calculationProgress.totalEstimatedDistance = (float) (MapUtils.getDistance(start, end) / speed);
} }
} }
@ -226,7 +230,7 @@ public class TransportRoutePlanner {
sg.walkDist = p.parentRoute.walkDist; sg.walkDist = p.parentRoute.walkDist;
sg.walkTime = sg.walkDist / ctx.cfg.walkSpeed; sg.walkTime = sg.walkDist / ctx.cfg.walkSpeed;
sg.depTime = p.departureTime; sg.depTime = p.departureTime;
sg.travelInaccurateDist = p.parentTravelDist; sg.travelDistApproximate = p.parentTravelDist;
sg.travelTime = p.parentTravelTime; sg.travelTime = p.parentTravelTime;
route.segments.add(0, sg); route.segments.add(0, sg);
} }
@ -294,7 +298,7 @@ public class TransportRoutePlanner {
private static final int DISPLAY_SEGMENT_IND = 0; private static final int DISPLAY_SEGMENT_IND = 0;
public TransportRoute route; public TransportRoute route;
public double walkTime; public double walkTime;
public double travelInaccurateDist; public double travelDistApproximate;
public double travelTime; public double travelTime;
public int start; public int start;
public int end; public int end;
@ -322,6 +326,10 @@ public class TransportRoutePlanner {
return -1; return -1;
} }
public double getTravelTime() {
return travelTime;
}
public TransportStop getStart() { public TransportStop getStart() {
return route.getForwardStops().get(start); return route.getForwardStops().get(start);
} }
@ -478,18 +486,21 @@ public class TransportRoutePlanner {
} }
public double getTravelTime() { public double getTravelTime() {
if(cfg.useSchedule) { double t = 0;
int t = 0; for (TransportRouteResultSegment s : segments) {
for(TransportRouteResultSegment s : segments) { if (cfg.useSchedule) {
TransportSchedule sts = s.route.getSchedule(); TransportSchedule sts = s.route.getSchedule();
for (int k = s.start; k < s.end; k++) { for (int k = s.start; k < s.end; k++) {
t += sts.getAvgStopIntervals()[k] * 10; t += sts.getAvgStopIntervals()[k] * 10;
} }
} else {
if (t > 0) {
t += cfg.getBoardingTime();
}
t += s.getTravelTime();
} }
return t;
} }
return getTravelDist() / cfg.travelSpeed + cfg.stopTime * getStops() + return t;
cfg.getChangeTime() * getChanges();
} }
public double getWalkTime() { public double getWalkTime() {

View file

@ -1,5 +1,14 @@
package net.osmand.router; 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 class TransportRoutingConfiguration {
public static final String KEY = "public_transport"; public static final String KEY = "public_transport";
@ -10,52 +19,94 @@ public class TransportRoutingConfiguration {
public int walkChangeRadius = 300; public int walkChangeRadius = 300;
public double walkSpeed = 3.6 / 3.6; // m/s public int maxNumberOfChanges = 4;
public double travelSpeed = 36 / 3.6; // m/s
public int stopTime = 30;
public int changeTime = 300;
public int maxNumberOfChanges = 5;
public int finishTimeSeconds = 1200; public int finishTimeSeconds = 1200;
public int maxRouteTime = 60 * 60 * 10; // 10 hours 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 // 10 seconds based
public int scheduleTimeOfDay = 12 * 60 * 6; // 12:00 - 60*6*12 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 scheduleMaxTime = 50 * 6; // TODO not appropriate variable, should be dynamic
public int scheduleMinChangeTime = 180; // 3 min
// day since 2000 // day since 2000
public int scheduleDayNumber; 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() { public int getChangeTime() {
return useSchedule ? scheduleMinChangeTime : changeTime; return useSchedule ? 0 : changeTime;
}
public int getBoardingTime() {
return boardingTime;
} }
public TransportRoutingConfiguration(RoutingConfiguration.Builder builder) { public TransportRoutingConfiguration(RoutingConfiguration.Builder builder) {
GeneralRouter router = builder == null ? null : builder.getRouter("public_transport"); this(builder, Collections.emptyMap());
if(router != null) { }
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); 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); ZOOM_TO_LOAD_TILES = router.getIntAttribute("zoomToLoadTiles", ZOOM_TO_LOAD_TILES);
maxNumberOfChanges = router.getIntAttribute("maxNumberOfChanges", maxNumberOfChanges); maxNumberOfChanges = router.getIntAttribute("maxNumberOfChanges", maxNumberOfChanges);
maxRouteTime = router.getIntAttribute("maxRouteTime", maxRouteTime); maxRouteTime = router.getIntAttribute("maxRouteTime", maxRouteTime);
finishTimeSeconds = router.getIntAttribute("delayForAlternativesRoutes", finishTimeSeconds); 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);
} }
} }