/** @return an array of MergePaths */ function completePath($startPath, $endPath, $line, $duration) { $debug = true; outputDebug("algorithm.completePath({$duration})", $debug); outputDebug("duration = " . $duration, $debug); /* The startPath runs from start to finish. The endPath runs from finish to start. We need to combine based on the line that we found. We know that eventually we'll go down the line until we hit the other path. We don't know if we're on the line or not. If we already are, then we're only going in one direction. */ $finished = "continue"; $currentStation = $startPath->getCurrentStation(); $currentLine = $currentStation->getLine($line->name); $connections = $currentLine->getConnections(); foreach ($connections as $connection) { outputDebug("completePath() connection = " . $connection->id, $debug); if ($connection->id == $startPath->getLastStation()->getID()) { continue; } // $path = $startPath->createCopy(); // create a new segment from the connection $nextStation = retrieveStation($connection->id); // check to see if it's the destination or if it's visited $visited = isVisited($nextStation, $startPath->visited); if ($visited) { // we only care to go in the forward direction outputDebug("continuePath() :: already visited.", $debug); continue; } /*$lines = $currentStation->getOverlapLines($nextStation); $segment = new Segment($currentStation, $nextStation, $lines, $connection->duration, $connection->type); if ($debug) { echo "created segment: " . $segment->toString() . "<br/>\n"; } $path->addSegment($segment, new Box($nextStation->point, $path->getDestination()->point)); if ($debug) { echo "<br/>\n" . $path->toString() . "<br/>\n"; }*/ $path = new Path($startPath, $nextStation, $currentLine, $connection); outputDebug("current path = " . $path->toString(), $debug); if ($duration > 0 && $path->duration > $duration) { outputDebug("duration is longer than an already completed path. discard.", $debug); return; } if ($nextStation == $endPath->getCurrentStation()) { outputDebug("algorithm.completePath() : found match, creating completed path", $debug); return mergePaths($path, $endPath); } $pathArray = array(); $pathArray[] = $path; $newPathArray = array(); while (count($pathArray) > 0) { $newPath = array_shift($pathArray); if ($debug) { echo "loop:<br/>\n" . $newPath->toString() . "<br/>\n"; } $array = continuePath($newPath, $endPath->getCurrentStation(), $currentLine->name); outputDebug("found " . count($array) . " paths.", $debug); foreach ($array as $metaPath) { outputDebug($metaPath->getStatus() . " " . $metaPath->path->toString(), $debug); /* status: 0 = continued path, 1 = match with end path found, 2 = end of line, 3 = found destination */ if ($metaPath->getStatus() == "found") { if ($duration <= 0 && $metaPath->path->duration < $duration) { $area = $metaPath->path->getBox()->getArea(); $oldArea = $startPath->getBox()->getArea(); if ($area < $oldArea) { return $metaPath->path; } } } if ($metaPath->getStatus() == "match") { $pathDuration = $metaPath->path->duration; if ($duration <= 0 || $metaPath->path->duration < $duration) { $area = $metaPath->path->getBox()->getArea(); $oldArea = $startPath->getBox()->getArea(); if ($area < $oldArea) { outputDebug("returning completed path: " . $metaPath->path->toString(), $debug); return mergePaths($metaPath->path, $endPath); } } } // check area of the path $area = $metaPath->path->getBox()->getArea(); $oldArea = $newPath->getBox()->getArea(); if ($area < $oldArea) { if ($duration <= 0 || $duration > $metaPath->path->duration) { outputDebug("adding path to list.", $debug); $newPathArray[] = $metaPath->path; } } } if (count($pathArray) == 0) { $newCount = count($newPathArray); if ($newCount > 0) { outputDebug("pathArray exhausted. newPathArray ({$newCount}) set.", $debug); $pathArray = $newPathArray; $newPathArray = array(); } } } } outputDebug("1. directions have already been visited or 2. end of the line or 3. there is already a better path.", $debug); return null; }
/** @return an array of MergePaths */ function completePath($startPath, $endPath, $line, $duration) { $debug = true; outputDebug("algorithm.completePath()", $debug); outputDebug("duration = " . $duration, $debug); /* The startPath runs from start to finish. The endPath runs from finish to start. We need to combine based on the line that we found. We know that eventually we'll go down the line until we hit the other path. We don't know if we're on the line or not. If we already are, then we're only going in one direction. */ $finished = 0; $currentStation = $startPath->getCurrentStation(); $currentLine = $currentStation->getLine($line->name); $connections = $currentLine->getConnectionList($startPath->getLastStation()->getID()); foreach ($connections as $connection) { // $path = $startPath->createCopy(); // create a new segment from the connection $nextStation = retrieveStation($connection->id); // check to see if it's the destination or if it's visited $visited = isVisited($nextStation, $startPath->visited); if ($visited) { // we only care to go in the forward direction if ($debug) { echo "continuePath() :: already visited.<br/>\n"; } continue; } /*$lines = $currentStation->getOverlapLines($nextStation); $segment = new Segment($currentStation, $nextStation, $lines, $connection->duration, $connection->type); if ($debug) { echo "created segment: " . $segment->toString() . "<br/>\n"; } $path->addSegment($segment, new Box($nextStation->point, $path->getDestination()->point)); if ($debug) { echo "<br/>\n" . $path->toString() . "<br/>\n"; }*/ $path = new Path($startPath, $nextStation, $currentLine, $connection); if ($duration > 0 && $path->duration > $duration) { if ($debug) { echo "duration is longer than an already completed path. discard.<br/>\n"; } return null; } if ($nextStation == $endPath->getCurrentStation()) { if ($debug) { echo "algorithm.completePath() : found match, creating completed path<br/>\n"; } return mergePaths($path, $endPath); } while ($finished == 0 && $path->getCurrentStation() != $endPath->getCurrentStation()) { if ($debug) { echo "loop:<br/>\n" . $path->toString() . "<br/>\n"; } $array = continuePath($path, $endPath->getCurrentStation(), $currentLine->name); foreach ($array as $metaPath) { /* status: 0 = continued path, 1 = match with end path found, 2 = end of line, 3 = found destination */ if ($metaPath->status == 3) { if ($duration > 0 && $path->duration < $duration) { $area = $metaPath->path->getBox()->getArea(); $oldArea = $startPath->getBox()->getArea(); if ($area < $oldArea) { return $metaPath->path; } } } if ($metaPath->status == 1) { if ($duration > 0 && $path->duration < $duration) { $area = $metaPath->path->getBox()->getArea(); $oldArea = $startPath->getBox()->getArea(); if ($area < $oldArea) { return mergePaths($metaPath->path, $endPath); } } } if ($finished != 0 && $metaPath->status == 0) { $path = $metaPath->path; $finished == 0; } else { $finished = $metaPath->status; } } } } if ($debug) { echo "could not find a path because both directions either have been visited or are at the end of the line.<br/>\n"; } return null; }