package tmcsim.utilities; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * OBSOLETE since deprecating ATMS functionality. No longer used. * This utility program is used to create the highway map file used as part * of the configuration files needed by the simulator. * It merges info from three input files to create highway map file. * Input: 1. VDS file is the district VDS metadata file downloaded from the PeMS * Data Clearinghouse. It gives identifying info about each VDS. * 2. Loop detector (lane) file that we found on the ATMS server. * It lists all the lanes associated with each VDS. * 3. LDS file that has the fep line number for each LDS. * Output: 1. The highway map file that lists VDS info and the lanes it governs, * in a format similar to what FEP simulator uses. * @author jdalbey, jtorres */ public class BuildHighwayFile { final public static String dirpath = "config/vds_data/old_vds_data/"; final public static String vdsFileName = "d12_vds_meta.txt"; final public static String loopFileName = "cleaned_chu_atms_loop_data.txt"; final public static String ldsFileName = "cleaned_chu_atms_lds_data.txt"; final public static String highwayFile = "highways_complete.txt"; /** A dictionary of ldsIDs to VDSids */ Map ldsDict; /** A dictionary of all VDSids linked to a given FEP line number */ Map> feplines; /** A dictionary to lookup VDS data given vdsID */ Map vdsDict; /** A list of used VDS ids - FOR DEBUGGING*/ Set vdsUsed = new HashSet(); int ignored = 0; // count of ignored VDS ids /** IDs Reported missing during lookup */ Set missingVDS = new HashSet(); Set missingLDS = new HashSet(); /** Once all the input data has been read and the lookup dictionaries * created we can build the highway file. */ public void createHighwayFile() { try { PrintWriter hwyWriter = new PrintWriter(new File(dirpath+highwayFile)); hwyWriter.print(feplines.size()+"\n"); // for each fep line for (String fep_line: feplines.keySet()) { hwyWriter.print(fep_line+" 0 "); List vdsList = feplines.get(fep_line); hwyWriter.print(vdsList.size()+"\n"); // output the vds info for (String vds: vdsList) { VehicleDetectionStation vdsItem = vdsDict.get(vds); if (vdsItem == null) { System.out.println(vds + " not found in vdsDict"); } else { // Output the VDS identifying info hwyWriter.print(vdsItem.id + " "); hwyWriter.print(vdsItem.toString() + " "); hwyWriter.print(vdsItem.getLaneList().size() + " "); hwyWriter.print(vdsItem.street+"\n"); List laneList = vdsItem.getLaneList(); // output all the lanes for (String lane: laneList) { hwyWriter.print(lane); hwyWriter.print("\n"); } } } } hwyWriter.close(); }catch (FileNotFoundException ex) { Logger.getLogger(BuildHighwayFile.class.getName()).log(Level.SEVERE, null, ex); } catch (Exception ex) { ex.printStackTrace(); Logger.getLogger(BuildHighwayFile.class.getName()).log(Level.SEVERE, null, ex); } } /** Read the loop file to create a dictionary to lookup all the lanes * for a given VDS. */ public void createLanelookup() { feplines = new HashMap> (); try { Scanner loopScanner = new Scanner(new File(dirpath+loopFileName)); loopScanner.nextLine(); // Skip the column headers // Read all the lines in the loop file while(loopScanner.hasNextLine()) { String line = loopScanner.nextLine(); Scanner lineScanner = new Scanner(line); Integer fwy = lineScanner.nextInt(); String dir = lineScanner.next(); String postmile = lineScanner.next(); String ldsID = lineScanner.next(); String vdsID = lineScanner.next(); String loopID = lineScanner.next(); String shortLoc = lineScanner.next(); Integer laneNum = lineScanner.nextInt(); String loop_name = lineScanner.nextLine().trim(); // String loop_name = line.substring(73).trim(); // grab rest of line loop_name = loop_name.replace(" ", "_"); lineScanner.close(); // Combine fields for one lane description String laneDesc = loopID + " " + shortLoc + " " + loop_name; // Add the lane to the lookup table if (vdsDict.containsKey(vdsID)) { vdsDict.get(vdsID).addLane(laneDesc); vdsUsed.add(vdsID); } else { // If we're missing a VDS id record it // but we're only interested in two lane types. boolean desiredType = shortLoc.equals("ML") || shortLoc.equals("OS"); if (desiredType && !missingVDS.contains(vdsID)) { System.out.println("createLaneLookup(): vdsID: "+vdsID+ " of type "+shortLoc+" not found. "+ String.format("%3s %s %5s",fwy,dir,postmile)); missingVDS.add(vdsID); } } // Also Add this vdsID to the list associated with a fepline // lookup which fepline to use for this VDS (using ldsid as // intermediate key. StationAddr sa = ldsDict.get(ldsID); if (sa == null) { if (!missingLDS.contains(ldsID)) { System.out.println("missing ldsID in Station Addr lookup: "+ldsID+" "+ String.format("%3s %s %5s",fwy,dir,postmile)); missingLDS.add(ldsID); } } else { String fep_line = sa.line_num; // Fetch the info about this VDS VehicleDetectionStation curr = vdsDict.get(vdsID); // Some VDS were ignored because they weren't Mainline if (curr != null) { // Assign the station address for this VDS curr.setStaAddr(ldsDict.get(ldsID).station_address); if (fep_line == null) { System.out.println("No fepline for ldsID "+ldsID+ " :vdsid " +vdsID+" "+fwy+dir+postmile); } else { // Add vdsID to list of feplines if (feplines.containsKey(fep_line)) { List vdsList = feplines.get(fep_line); // only add it if it isn't already there if (!vdsList.contains(vdsID)) { feplines.get(fep_line).add(vdsID); } } else // Create a new one { List arraylist1 = new ArrayList(); arraylist1.add(vdsID); feplines.put(fep_line, arraylist1); } } } } } loopScanner.close(); } catch (FileNotFoundException ex) { Logger.getLogger(BuildHighwayFile.class.getName()).log(Level.SEVERE, null, ex); } } /** Create a dictionary of VehicleDetectionStations */ public void createVDSdict() { vdsDict = new HashMap(); try { Scanner vdsScanner = new Scanner(new File(dirpath+vdsFileName)); // Read the tab-delimited vds file while(vdsScanner.hasNextLine()) { String line = vdsScanner.nextLine(); Scanner lineScanner = new Scanner(line).useDelimiter("\t"); VehicleDetectionStation vds = new VehicleDetectionStation(lineScanner); // We only want stations that are mainline, ignore offramps, etc. if (vds.type.equals("ML")) { vdsDict.put(vds.id, vds); } else { ignored++; } lineScanner.close(); } vdsScanner.close(); System.out.println("Ignored "+ignored+ " non-Mainline VDS's"); } catch (FileNotFoundException ex) { Logger.getLogger(BuildHighwayFile.class.getName()).log(Level.SEVERE, null, ex); } } /** Read the lds file to create a dictionary to lookup the FEP line number. */ public void createLDSdict() { ldsDict = new HashMap (); try { Scanner ldsScanner = new Scanner(new File(dirpath+ldsFileName)); ldsScanner.nextLine(); // Skip the column headers // Read all the lines in the loop file while(ldsScanner.hasNextLine()) { String line = ldsScanner.nextLine(); Scanner lineScanner = new Scanner(line); String ldsID = lineScanner.next(); String line_num = lineScanner.next(); String stn_address = lineScanner.next(); // Save the fep linenum and station address for this LDS StationAddr sa = new StationAddr(line_num,stn_address); lineScanner.close(); // Add the ldsID to the dict ldsDict.put(ldsID, sa); } ldsScanner.close(); } catch (FileNotFoundException ex) { Logger.getLogger(BuildHighwayFile.class.getName()).log(Level.SEVERE, null, ex); } } /** Display the set of VDS in the dict that didn't get used (weren't found * in loop file. */ public void showLeftoverVDS() { Set vdsItems = vdsDict.keySet(); // get all the VDS ids vdsItems.removeAll(vdsUsed); // remove the ones that were used System.out.println("Here are the unused VDS ids:"); // list the remaining items for (String vdsitem: vdsItems) { System.out.print(vdsitem+" "); } System.out.println(""); } /** * @param args the command line arguments */ public static void main(String[] args) { BuildHighwayFile app = new BuildHighwayFile(); app.createLDSdict(); app.createVDSdict(); app.createLanelookup(); app.createHighwayFile(); System.out.println("Build complete, output file: "+highwayFile); } /** A record for a fep line_num and Station Address pair */ final class StationAddr { public final String line_num; public final String station_address; public StationAddr(String line, String addr) { this.line_num = line; this.station_address = addr; } } }