package helpers;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import roadnetwork.Edge;
import simulation.Simulation;
import classes.Project;
/**
* Helper class providing a method that joins multiple trips into one.
*
*/
public class MultipleTripExpander {
/**
* Creates a complete route that passes through all the edges in the
* {@link tripEdges} list. SUMO has the limitation that it can create routes
* for a trip that defines the starting and ending edges only. This method
* calculates the routes for a trip that is defined by multiple edges.
*
* @param tripEdges
* A list of edges defining the route.
* @return a space separated list of the ids of the edges that define the
* complete route
* @throws Exception
* if anything goes wrong
*/
public static String ExpandTrips(List<Edge> tripEdges) throws Exception {
Simulation sim = Project.getCurrentlyLoadedProject().getSimulation();
String simulationPath = sim.getExportPath();
String roadNetworkFile = sim.getName() + ".net.xml";
File tripsToExpand = new File(simulationPath + File.separator + "tripstoexpand.tmp");
File expandedTrips = new File(simulationPath + File.separator + "expandedtrips.tmp");
File expandedTripsAlt = new File(simulationPath + File.separator + "expandedtrips.tmp.alt");
// Create a temporary trip file
BufferedWriter tripout = new BufferedWriter(new FileWriter(tripsToExpand));
// Write the trips that are defined from the edges in the tripEdges
// parameter.
// Each consecutive pair of edges define a trip
tripout.write("<trips>\n");
for (int i = 1; i < tripEdges.size(); i++) {
tripout.write("<trip " + "id=\"" + String.valueOf(i) + "\" " + "depart=\"" + String.valueOf(i) + "\" " + "from=\"" + tripEdges.get(i - 1).getId() + "\" " + "to=\"" + tripEdges.get(i).getId() + "\" />\n");
}
tripout.write("</trips>");
tripout.close();
// Run SUMO duarouter to find the routes for the trips
List<String> args = new ArrayList<String>();
args.add("\"" + ApplicationSettings.getDUARouterPath() + "\"");
args.add("-t=\"tripstoexpand.tmp\"");
args.add("-n=\"" + roadNetworkFile + "\"");
args.add("-o=\"expandedtrips.tmp\"");
args.add("--continue-on-unbuild");
ProcessBuilder pb = new ProcessBuilder(args);
pb.directory(new File(simulationPath));
Process dua = pb.start();
StreamGobbler gi = new StreamGobbler(dua.getInputStream());
StreamGobbler ge = new StreamGobbler(dua.getErrorStream());
gi.start();
ge.start();
int exitvalue = dua.waitFor();
gi.stop();
ge.stop();
// Read the output from DUARouter
List<String> gir = gi.getReadLines();
List<String> ger = ge.getReadLines();
for (String s : ger) {
System.out.println(s);
}
// Read the generated routes and return the result
List<String> allEdges = new ArrayList<String>();
BufferedReader generatedRoutes = new BufferedReader(new FileReader(expandedTrips));
String line = null;
int routesFound = 0;
// Read all lines
while ((line = generatedRoutes.readLine()) != null) {
// If the line is a route definition
if (line.contains("<route>")) {
// Get the edges of the route
String[] routeEdges = line.substring(line.indexOf("<route>") + 7, line.indexOf("</route>")).split(" ");
routesFound++;
// If this is the first route then add all the edges to the
// final list
if (routesFound == 1) {
for (int i = 0; i < routeEdges.length; i++) {
allEdges.add(routeEdges[i]);
}
}
// For all the rest routes add all but the first edges
else {
for (int i = 1; i < routeEdges.length; i++) {
allEdges.add(routeEdges[i]);
}
}
}
}
// Remove temporary files
if (expandedTrips.exists()) {
expandedTrips.delete();
}
if (expandedTripsAlt.exists()) {
expandedTripsAlt.delete();
}
if (tripsToExpand.exists()) {
tripsToExpand.delete();
}
// Connect all the edges into one string
StringBuilder resultBuilder = new StringBuilder();
for (String s : allEdges) {
resultBuilder.append(s + " ");
}
return resultBuilder.toString();
}
}