private OsmTrack compileTrip(ScheduledTrip trip, int offset) { OsmTrack track = new OsmTrack(); track.iternity = new ArrayList<String>(); ScheduledTrip current = trip; ScheduledLine lastLine = new ScheduledLine(); ScheduledLine dummyLine = new ScheduledLine(); List<ScheduledTrip> list = new ArrayList<ScheduledTrip>(); int distance = 0; ScheduledTrip itrip = null; String profile = extractProfile(rc.localFunction); OsmNodeP nextNode = null; while (current != null) { System.out.println("trip=" + current); OsmNodeP node = current.getTargetNode(); OsmPathElement pe = new OsmPathElement(node.ilon, node.ilat, node.selev, null); track.addNode(pe); if (nextNode != null) { distance += node.calcDistance(nextNode); } boolean isScheduled = current.link instanceof ScheduledLink; boolean isConnection = current.link.descriptionBitmap == null && !isScheduled; ScheduledLine line = isScheduled ? ((ScheduledLink) current.link).line : isConnection ? dummyLine : null; if (line != lastLine && !isConnection) { itrip = new ScheduledTrip(); itrip.departure = current.departure; itrip.arrival = current.arrival; itrip.originNode = current.originNode; itrip.link = current.link; if (isScheduled && list.size() > 0) { list.get(list.size() - 1).originNode = current.getTargetNode(); } list.add(itrip); } else if (itrip != null && !isConnection) { itrip.departure = current.departure; itrip.originNode = current.originNode; } lastLine = line; current = current.origin; nextNode = node; } track.distance = distance; track.cost = trip.cost; for (int i = list.size() - 1; i >= 0; i--) { current = list.get(i); String lineName = profile; boolean isScheduled = current.link instanceof ScheduledLink; if (isScheduled) { lineName = ((ScheduledLink) current.link).line.name; } String stationName = "*position*"; if (current.originNode instanceof StationNode) { stationName = ((StationNode) current.originNode).name; } String nextStationName = "*position*"; if (i > 0 && list.get(i - 1).originNode instanceof StationNode) { nextStationName = ((StationNode) list.get(i - 1).originNode).name; } { Date d0 = new Date(time0 + 60000L * offset + current.departure); Date d1 = new Date(time0 + 60000L * offset + current.arrival); if (track.iternity.size() > 0) track.iternity.add(""); track.iternity.add("depart: " + d0 + " " + stationName); track.iternity.add(" --- " + lineName + " ---"); track.iternity.add("arrive: " + d1 + " " + nextStationName); } } return track; }
private void addNextTripsForLink( ScheduledTrip trip, OsmNodeP currentNode, OsmLinkP currentLink, OsmLinkP link, OffsetSet offsets, int level) { if (link == currentLink) { return; // just reverse, ignore } OsmNodeP node = link.getTarget(currentNode); if (node == null) { System.out.println("ups2: " + link); return; } // calc distance and check nogos rc.nogomatch = false; int distance = rc.calcDistance(currentNode.ilon, currentNode.ilat, node.ilon, node.ilat); if (rc.nogomatch) { return; } if (link instanceof ScheduledLink) { // System.out.println( "next trip for link: " + link + " at offset " + offsets ); ScheduledLink slink = (ScheduledLink) link; ScheduledLine line = slink.line; // line change delay long delay = 0L; if (currentLink instanceof ScheduledLink) { delay = ((ScheduledLink) currentLink).line == line ? 0L : (long) (rc.changetime * 1000.); // 3 minutes } long changePenalty = delay > 0 ? 60000L : 0L; List<ScheduledDeparture> nextDepartures = line.getScheduledDepartures(slink.indexInLine, time0 + trip.arrival + delay, offsets); for (ScheduledDeparture nextDeparture : nextDepartures) { ScheduledTrip nextTrip = new ScheduledTrip(nextDeparture.offsets, link, currentNode, trip); long waitTime = nextDeparture.waitTime + delay; long rideTime = nextDeparture.rideTime; nextTrip.cost = trip.cost + (int) ((rideTime + changePenalty + waitTime * rc.waittimeadjustment) * rc.cost1speed / 3600.); // 160ms / meter = 22km/h nextTrip.departure = trip.arrival + waitTime; nextTrip.arrival = nextTrip.departure + rideTime; addToOpenSet(nextTrip); // System.out.println( "found: " + nextTrip ); } } else if (link.isWayLink()) { // get costfactor rc.expctxWay.evaluate(link.isReverse(currentNode), link.descriptionBitmap, null); // *** penalty for distance float costfactor = rc.expctxWay.getCostfactor(); if (costfactor > 9999.) { return; } int waycost = (int) (distance * costfactor + 0.5f); // *** add initial cost if factor changed float costdiff = costfactor - trip.lastcostfactor; if (costdiff > 0.0005 || costdiff < -0.0005) { waycost += (int) rc.expctxWay.getInitialcost(); } if (node.getNodeDecsription() != null) { rc.expctxNode.evaluate( rc.expctxWay.getNodeAccessGranted() != 0., node.getNodeDecsription(), null); float initialcost = rc.expctxNode.getInitialcost(); if (initialcost >= 1000000.) { return; } waycost += (int) initialcost; } // *** penalty for turning angles if (trip.originNode != null) { // penalty proportional to direction change double cos = rc.calcCosAngle( trip.originNode.ilon, trip.originNode.ilat, currentNode.ilon, currentNode.ilat, node.ilon, node.ilat); int turncost = (int) (cos * rc.expctxWay.getTurncost() + 0.2); // e.g. turncost=90 -> 90 degree = 90m penalty waycost += turncost; } ScheduledTrip nextTrip = new ScheduledTrip(offsets, link, currentNode, trip); // *** penalty for elevation short ele2 = node.selev; short ele1 = trip.selev; int elefactor = 250000; if (ele2 == Short.MIN_VALUE) ele2 = ele1; nextTrip.selev = ele2; if (ele1 != Short.MIN_VALUE) { nextTrip.ehbd = trip.ehbd + (ele1 - ele2) * elefactor - distance * rc.downhillcutoff; nextTrip.ehbu = trip.ehbu + (ele2 - ele1) * elefactor - distance * rc.uphillcutoff; } if (nextTrip.ehbd > rc.elevationpenaltybuffer) { int excess = nextTrip.ehbd - rc.elevationpenaltybuffer; int reduce = distance * rc.elevationbufferreduce; if (reduce > excess) { reduce = excess; } excess = nextTrip.ehbd - rc.elevationmaxbuffer; if (reduce < excess) { reduce = excess; } nextTrip.ehbd -= reduce; if (rc.downhillcostdiv > 0) { int elevationCost = reduce / rc.downhillcostdiv; waycost += elevationCost; } } else if (nextTrip.ehbd < 0) { nextTrip.ehbd = 0; } if (nextTrip.ehbu > rc.elevationpenaltybuffer) { int excess = nextTrip.ehbu - rc.elevationpenaltybuffer; int reduce = distance * rc.elevationbufferreduce; if (reduce > excess) { reduce = excess; } excess = nextTrip.ehbu - rc.elevationmaxbuffer; if (reduce < excess) { reduce = excess; } nextTrip.ehbu -= reduce; if (rc.uphillcostdiv > 0) { int elevationCost = reduce / rc.uphillcostdiv; waycost += elevationCost; } } else if (nextTrip.ehbu < 0) { nextTrip.ehbu = 0; } nextTrip.lastcostfactor = costfactor; nextTrip.cost = trip.cost + (int) (waycost * rc.additionalcostfactor + 0.5); nextTrip.departure = trip.arrival; nextTrip.arrival = nextTrip.departure + (long) (waycost * 3600. / rc.cost1speed); // 160ms / meter = 22km/h addToOpenSet(nextTrip); } else // connecting link { ScheduledTrip nextTrip = new ScheduledTrip(offsets, link, currentNode, trip); long delay = (long) (rc.buffertime * 1000.); // 2 min nextTrip.cost = trip.cost + (int) (delay * rc.waittimeadjustment * rc.cost1speed / 3600.); nextTrip.departure = trip.arrival; nextTrip.arrival = nextTrip.departure + delay; addToOpenSet(nextTrip); } }