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); } }