import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * <code>MapPoint</code> is a utility class that uses the MapPointDist library to evaluate a time and distance matrix * using MapPoint. * <p> * Creation date: Jun 12, 2012 - 4:02:13 PM * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a * href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a * href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 */ public class MapPointDist { /** The separator for CSV files */ public static String sSeparator = ";"; /** Path to the MapPointDist executable */ public static String sMapPointPath = "../Libraries/mappointdist/MapPointDist.exe"; /** * Generate a file containing all the coordinates, and two files containing the corresponding distance and time * matrices * * @param coordinates * an array containing the coordinates of all points * @param coordFile * the file in which the coordinates will be written * @param destFile * the file in which the matrices will be written * @param symmetric * {@code true} if the instance is symmetric, {@code false} otherwise * @throws IOException */ public static void generateDistanceTimeMatrixFiles(double[][] coordinates, String coordFile, String destFile, boolean symmetric) throws IOException { // Write the coordinates file String formatString = "%s" + sSeparator + "%s" + sSeparator + "%s\n"; BufferedWriter out = new BufferedWriter(new FileWriter(coordFile)); out.write(String.format(formatString, "id", "x", "y")); for (int i = 0; i < coordinates.length; i++) { out.write(String.format(formatString, i, coordinates[i][0], coordinates[i][1])); } out.flush(); out.close(); Process calc = Runtime.getRuntime().exec( new String[] { sMapPointPath, coordFile, destFile, "" + symmetric, "" + Runtime.getRuntime().availableProcessors() }); try { System.out.println(( "MapPointDist: Calculating distance and time matrix for file "+ coordFile); calc.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } if (calc.exitValue() != 0) { throw new IllegalStateException("The MapPoint subprocess exited with value " + calc.exitValue()); } } /** * Evaluate the distance and time matrices * * @param coordinates * an array containing the coordinates of all points * @param coordFile * the file in which the coordinates will be written * @param destFile * the file in which the matrices will be written * @param symmetric * {@code true} if the instance is symmetric, {@code false} otherwise * @return an array of dimension [2][size][size] containing the distances matrix in the first index and the times in * the second * @throws IOException * @see {@link #generateDistanceTimeMatrixFiles(String, String, String)} */ public static double[][][] evaluateDistanceTimeMatrix(double[][] coordinates, String coordFile, String destFile, boolean symmetric) throws IOException { generateDistanceTimeMatrixFiles(coordinates, coordFile, destFile, symmetric); return loadDistanceTimeMatrix(destFile); } /** * Load a distance and travel time matrix from a file generated by {@code MapPointDist}. * <p> * Note that even if the matrices are symmetric, the full matrices will be returned * </p> * * @param dataFile * the file containing the matrices * @return an array of dimension [2][size][size] containing the distances matrix in the first index and the times in * the second * @throws IOException */ public static double[][][] loadDistanceTimeMatrix(String dataFile) throws IOException { BufferedReader in = new BufferedReader(new FileReader(dataFile)); int type = 0; String row = in.readLine(); String[] cols = row.split(sSeparator); int size = Integer.valueOf(cols[0]); boolean symmetric = Boolean.valueOf(cols[1]); row = in.readLine(); double[][][] matrix = new double[2][size][size]; int i = 0; while (row != null) { if (row.contains("TIMES")) type = 1; else if (row.contains("DISTANCES")) type = 0; cols = row.split(sSeparator); if (cols.length > 1) { i = Integer.valueOf(cols[0]); for (int j = 1; j < cols.length; j++) { if (symmetric) { matrix[type][i][i + j] = Double.valueOf(j); matrix[type][i + j][i] = matrix[type][i][i + j]; } else { matrix[type][i][j - 1] = Double.valueOf(j); } } } row = in.readLine(); } return matrix; } }