Changeset 184 in tmcsimulator for trunk/src/atmsdriver/model/Highways.java


Ignore:
Timestamp:
10/28/2017 05:24:02 PM (9 years ago)
Author:
jtorres
Message:

highways.java: converted to immutable, removed use of FEPLineLoader and added loadLines(), loadLine(), loadStation(), and loadLoop() methods. Renamed loadHighways() to configureHighways(), renamed writeHighwaysMeta() to getHighwaysMeta() which now returns a String containing metadata instead of opening a file and writing to it, which is more flexible. FEPLineLoader.java: deleted, no longer need it. FEPLine.java: converted to immutable, removed unnecessary member variables and adjusted all methods accordingly. Station.java: MLTotVol() and OppTotVol?() are now being updated at end of updateByDirection(). ATMSDriver.java: Now using one config file: highways_fullmap.txt, as opposed to the older lds.txt and loop.txt files. config/vds_data: added highways_fullmap.txt. config/atms_driver_config.properties, atms_driver_config_local.properties: updated config to reflect use of highways_fullmap.txt instead of old loop.txt and lds.txt configuration. ATMSBatchDriver.java: conformed highways initialization in constructor to reflect use of highways_fullmap.txt

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/atmsdriver/model/Highways.java

    r180 r184  
    11package atmsdriver.model; 
    22 
    3 import atmsdriver.FEPLineLoader; 
     3import atmsdriver.model.Station.DIRECTION; 
    44import java.io.File; 
    5 import java.io.FileWriter; 
     5import java.io.FileNotFoundException; 
    66import java.io.IOException; 
    77import java.io.PrintWriter; 
     
    1313import java.util.HashMap; 
    1414import java.util.Map; 
    15 import java.util.Observable; 
    16 import java.util.Observer; 
     15import java.util.Scanner; 
    1716import java.util.Set; 
    1817import java.util.logging.Level; 
     
    2928import tmcsim.common.SimulationException; 
    3029 
    31 /** The Highways class aggregates all Highway instances within a geographic 
    32  *  region, and all of the FEPLines within an electronic detector  
    33  *  network, in the same geographic region. An instance of Highways.java  
    34  *  comprises the underlying model for the ATMSDriver application. 
    35  *  
    36  *  Highways uses method writeToFEP() to communicate with the FEP Simulator.  
    37  *  It creates a socket client which sends the FEP Simulator a highways status 
    38  *  message over the socket. This message is in the XML format required by the  
    39  *  FEP Simulator, which is provided by the resident toXML() method. 
    40  *  
    41  *  Currently, there is no driving logic within the highways class. It is only 
    42  *  done through an instance of the ConsoleDriver.java class. Eventually, it 
    43  *  will receive incident data (from exchange.xml or better yet, directly from  
    44  *  the TMCSimulator itself) and drive the highways using resident logic. 
     30/** 
     31 * The Highways class aggregates all Highway instances within a geographic 
     32 * region, and all of the FEPLines within an electronic detector network, in the 
     33 * same geographic region. An instance of Highways.java comprises the underlying 
     34 * model for the ATMSDriver application. 
     35 * 
     36 * Highways uses method writeToFEP() to communicate with the FEP Simulator. It 
     37 * creates a socket client which sends the FEP Simulator a highways status 
     38 * message over the socket. This message is sent in the format required by the 
     39 * FEP Simulator. 
     40 * 
     41 * Currently, there is no driving logic within the highways class. It is only 
     42 * done through an instance of the ConsoleDriver.java class. Eventually, it will 
     43 * receive incident data (from exchange.xml or better yet, directly from the 
     44 * TMCSimulator itself) and drive the highways using resident logic. 
    4545 * 
    4646 * @author John A. Torres 
    4747 */ 
    48 public class Highways { 
    49  
    50     final private ArrayList<FEPLine> lines; 
     48final public class Highways 
     49{ 
     50 
    5151    final private String FEPHostName; 
    5252    final private int FEPPortNum; 
    5353     
     54    final private ArrayList<FEPLine> lines; 
    5455    final public ArrayList<Highway> highways; 
    55      
    56     public Highways(String ldsFileName, String loopsFileName, 
    57             String highwayMetaFileName, String FEPHostName, int FEPPortNum) { 
    58         /* 
    59          lines = loadLines(highwayMetaFileName); 
    60          System.out.println("SIZE: " + toXML().toCharArray().length); 
    61          */ 
    62  
    63         FEPLineLoader ldr = new FEPLineLoader(new File(ldsFileName), new File(loopsFileName)); 
    64         this.lines = (ArrayList<FEPLine>) ldr.getFEPLines(); 
     56 
     57    public Highways(String highwaysMapFileName, String FEPHostName, int FEPPortNum) 
     58    { 
     59        // load FEP Lines 
     60        lines = loadLines(highwaysMapFileName); 
     61        // configure and load highways 
     62        this.highways = configureHighways(); 
     63         
     64        // write to FEP host and port number 
    6565        this.FEPHostName = FEPHostName; 
    6666        this.FEPPortNum = FEPPortNum; 
    67         this.highways = loadHighways(); 
    68         //writeHighwaysMeta("hard.txt"); 
    69     } 
    70      
    71     private ArrayList<Highway> loadHighways() { 
     67    } 
     68 
     69    private ArrayList<Highway> configureHighways() 
     70    { 
    7271        System.out.println("Loading highways..."); 
    7372        // The list of highways to return 
    7473        ArrayList<Highway> highways = new ArrayList<Highway>(); 
    7574         
    76         Map<Integer, ArrayList<Station>> 
    77                 highwayMap = new HashMap<>(); 
     75        // map of hwy number to its list of stations 
     76        Map<Integer, ArrayList<Station>> highwayMap = new HashMap<>(); 
    7877         
     78        // iterate through FEPLines and get data to add to the above map 
    7979        for (FEPLine line : lines) 
    8080        { 
     81            // grab all stations from the current FEPLine 
    8182            ArrayList<Station> lineStations = (ArrayList<Station>) line.stations; 
    82             for(Station station : lineStations) 
     83            // iterate through each station in the list of stations 
     84            for (Station station : lineStations) 
    8385            { 
    8486                Integer hwyNum = station.routeNumber; 
    85  
    86                 if(!highwayMap.containsKey(hwyNum)) 
     87                 
     88                // if the map does not contain an entry for the highway, create 
     89                // a new entry (key/value pair) for the highway and instantiate 
     90                // the empty list of stations 
     91                if (!highwayMap.containsKey(hwyNum)) 
    8792                { 
    8893                    ArrayList<Station> stnList = new ArrayList<>(); 
    8994                    stnList.add(station); 
    9095                    highwayMap.put(hwyNum, stnList); 
    91                 } 
     96                }  
     97                // if the map does have an entry for the highway, add the current 
     98                // station to its list of stations 
    9299                else 
    93100                { 
     
    97104        } 
    98105         
     106        // get the set of highway numbers 
    99107        Set<Integer> hwyKeys = highwayMap.keySet(); 
    100         for(Integer hwyKey : hwyKeys) 
     108        // get the highway number and associated stations and create a new hwy 
     109        // and add the hwy to this.highways 
     110        for (Integer hwyKey : hwyKeys) 
    101111        { 
    102112            ArrayList<Station> hwyStations = highwayMap.get(hwyKey); 
    103113            Collections.sort(hwyStations); 
    104114            System.out.println("Loaded highway " + hwyKey + "..."); 
    105             highways.add(new Highway(hwyKey,  
     115            highways.add(new Highway(hwyKey, 
    106116                    hwyStations)); 
    107117        } 
     
    109119        return highways; 
    110120    } 
    111         /** 
    112      * Applies specified color to the specified highway stretch. Route number and 
    113      * direction specify the highway. Postmile and range specify the stretch of 
    114      * specified highway. Dot color is the color to be applied to the stretch. 
    115      *  
     121 
     122    /** 
     123     * Applies specified color to the specified highway stretch. Route number 
     124     * and direction specify the highway. Postmile and range specify the stretch 
     125     * of specified highway. Dot color is the color to be applied to the 
     126     * stretch. 
     127     * 
    116128     * @param routeNumber highway route number 
    117129     * @param direction highway direction 
     
    120132     * @param dotColor the color to be applied to specified highway stretch 
    121133     */ 
    122     public void applyColorToHighwayStretch(Integer routeNumber, Station.DIRECTION direction,  
    123             Double postmile, Double range, LoopDetector.DOTCOLOR dotColor) { 
    124         System.out.println("Applying " + dotColor.name() + " dots to highway "  
    125                 + routeNumber + " " + direction.name() + " at postmile "  
     134    public void applyColorToHighwayStretch(Integer routeNumber, Station.DIRECTION direction, 
     135            Double postmile, Double range, LoopDetector.DOTCOLOR dotColor) 
     136    { 
     137        System.out.println("Applying " + dotColor.name() + " dots to highway " 
     138                + routeNumber + " " + direction.name() + " at postmile " 
    126139                + postmile + " with a range of " + range + " miles..."); 
    127          
     140 
    128141        // Get the highway by route number 
    129142        Highway highway = getHighwayByRouteNumber(routeNumber); 
    130          
     143 
    131144        // start value for highway section, and end value for highway section 
    132145        // by postmile 
    133146        Double startPost; 
    134147        Double endPost; 
    135          
     148 
    136149        // postmiles increase from s to n and w to e 
    137          
    138150        // if the direction is south or west 
    139         if(direction.equals(Station.DIRECTION.SOUTH) || direction.equals(Station.DIRECTION.WEST)) 
     151        if (direction.equals(Station.DIRECTION.SOUTH) || direction.equals(Station.DIRECTION.WEST)) 
    140152        { 
    141153            // add range value to startPost to get 
     
    143155            startPost = postmile; 
    144156            endPost = postmile + range; 
    145              
     157 
    146158            // iterate through the stations, if within the specified highway 
    147159            // stretch, update the station by direction and apply dot color 
    148             for(Station station : highway.stations) 
    149             { 
    150                 if(station.postmile >= startPost && station.postmile <= endPost) 
     160            for (Station station : highway.stations) 
     161            { 
     162                if (station.postmile >= startPost && station.postmile <= endPost) 
    151163                { 
    152164                    station.updateByDirection(direction, dotColor); 
    153165                } 
    154166            } 
    155         } 
    156         // if the direction is north or east  
     167        } // if the direction is north or east  
    157168        else 
    158169        { 
    159             //subtract range value from startPost 
     170            // subtract range value from startPost 
    160171            // to get the end postmile value of the highway section 
    161172            startPost = postmile; 
    162173            endPost = postmile - range; 
    163              
     174 
    164175            // iterate through the stations, if within the specified highway 
    165176            // section, update the station by direction and apply dot color 
    166             for(Station station : highway.stations) 
    167             { 
    168                 if(station.postmile <= startPost && station.postmile >= endPost) 
     177            for (Station station : highway.stations) 
     178            { 
     179                if (station.postmile <= startPost && station.postmile >= endPost) 
    169180                { 
    170181                    station.updateByDirection(direction, dotColor); 
     
    174185        System.out.println(""); 
    175186    } 
    176  
    177     /* 
    178      private ArrayList<FEPLine> loadLines(String highwayMetaFileName) { 
    179      ArrayList<FEPLine> lines = new ArrayList<>(); 
    180      try { 
    181      Scanner sc = new Scanner(new File(highwayMetaFileName)); 
    182      String firstLine = sc.nextLine(); 
    183  
    184      Scanner linesc = new Scanner(firstLine); 
    185      int numLines = linesc.nextInt(); 
    186      linesc.close(); 
    187  
    188      for (int i = 0; i < numLines; i++) { 
    189      System.out.println("CURR: " + i); 
    190      lines.add(loadLine(sc)); 
    191      } 
    192      sc.close(); 
    193  
    194      } catch (FileNotFoundException ex) { 
    195      Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); 
    196      } 
    197      return lines; 
    198      } 
    199  
    200      private FEPLine loadLine(Scanner sc) { 
    201      String line = sc.nextLine(); 
    202      System.out.println(line); 
    203      Scanner scline = new Scanner(line); 
    204  
    205      int lineNum = scline.nextInt(); 
    206      int count = scline.nextInt(); 
    207      int numStations = scline.nextInt(); 
    208      ArrayList<Station> stations = new ArrayList<>(); 
    209      for (int i = 0; i < numStations; i++) { 
    210      stations.add(loadStation(sc, lineNum)); 
    211      } 
    212  
    213      return new FEPLine(lineNum, stations, count); 
    214      } 
    215  
    216      private Station loadStation(Scanner sc, int lineNum) { 
    217      String line = sc.nextLine(); 
    218      System.out.println(line); 
    219      Scanner scline = new Scanner(line); 
    220      int ldsID = scline.nextInt(); 
    221      int drop = scline.nextInt(); 
    222      int fwy = scline.nextInt(); 
    223      DIRECTION dir = DIRECTION.getEnum(scline.next()); 
    224      double postmile = scline.nextDouble(); 
    225      int numLoops = scline.nextInt(); 
    226      String location = getStationLoc(line); 
    227      ArrayList<LoopDetector> loops = new ArrayList<>(); 
    228      for (int i = 0; i < numLoops; i++) { 
    229      loops.add(loadLoop(sc)); 
    230      } 
    231  
    232      return new Station(lineNum, ldsID, drop, location, loops, fwy, dir, postmile); 
    233      } 
    234  
    235      private LoopDetector loadLoop(Scanner sc) { 
    236      String line = sc.nextLine(); 
    237      Scanner scline = new Scanner(line); 
    238  
    239      int loopID = scline.nextInt(); 
    240      int laneNum = scline.nextInt(); 
    241      String loopLoc = getLoopLoc(line); // NEED GET LOOPLOC 
    242      scline.close(); 
    243      return new LoopDetector(loopID, loopLoc, laneNum); 
    244      } 
    245  
    246      private String getLoopLoc(String line) { 
    247      Scanner sc = new Scanner(line); 
    248      sc.nextInt(); 
    249      sc.nextInt(); 
     187     
     188    /** 
     189     * Loads all FEPLines from the specified highways map file. 
     190     *  
     191     * @param highwaysMapFileName 
     192     * @return List of FEPLines 
     193     */ 
     194    private ArrayList<FEPLine> loadLines(String highwaysMapFileName) 
     195    { 
     196        ArrayList<FEPLine> lines = new ArrayList<>(); 
     197        try 
     198        { 
     199            Scanner sc = new Scanner(new File(highwaysMapFileName)); 
     200            String firstLine = sc.nextLine(); 
     201 
     202            Scanner linesc = new Scanner(firstLine); 
     203            int numLines = linesc.nextInt(); 
     204            linesc.close(); 
     205 
     206            for (int i = 0; i < numLines; i++) 
     207            { 
     208                lines.add(loadLine(sc)); 
     209            } 
     210            sc.close(); 
     211 
     212        } catch (FileNotFoundException ex) 
     213        { 
     214            Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); 
     215        } 
     216        return lines; 
     217    } 
     218     
     219    /** 
     220     * Loads a single FEP Line from the highways map file. 
     221     *  
     222     * @param sc scanner at the current FEPLine line 
     223     * @return FEPLine 
     224     */ 
     225    private FEPLine loadLine(Scanner sc) 
     226    { 
     227        String line = sc.nextLine(); 
     228        Scanner scline = new Scanner(line); 
     229 
     230        int lineNum = scline.nextInt(); 
     231        int count = scline.nextInt(); 
     232        int numStations = scline.nextInt(); 
     233        ArrayList<Station> stations = new ArrayList<>(); 
     234        for (int i = 0; i < numStations; i++) 
     235        { 
     236            stations.add(loadStation(sc, lineNum)); 
     237        } 
     238 
     239        return new FEPLine(lineNum, stations, count); 
     240    } 
     241     
     242    /** 
     243     * Loads a single Station from the highways map file 
     244     * @param sc scanner at the current station line 
     245     * @param lineNum the FEPLine number for the station 
     246     * @return Station 
     247     */ 
     248    private Station loadStation(Scanner sc, int lineNum) 
     249    { 
     250        String line = sc.nextLine(); 
     251        Scanner scline = new Scanner(line); 
     252        int ldsID = scline.nextInt(); 
     253        int drop = scline.nextInt(); 
     254        int fwy = scline.nextInt(); 
     255        DIRECTION dir = DIRECTION.toDirection(scline.next()); 
     256        double postmile = scline.nextDouble(); 
     257        int numLoops = scline.nextInt(); 
     258        String location = getStationLoc(line); 
     259        ArrayList<LoopDetector> loops = new ArrayList<>(); 
     260        for (int i = 0; i < numLoops; i++) 
     261        { 
     262            loops.add(loadLoop(sc)); 
     263        } 
     264 
     265        return new Station(lineNum, ldsID, drop, location, loops, fwy, dir, postmile); 
     266    } 
     267     
     268    /** 
     269     * Loads a single loop from the highways map file 
     270     * 
     271     * @param sc scanner at the current loop line 
     272     * @return LoopDetector 
     273     */ 
     274    private LoopDetector loadLoop(Scanner sc) 
     275    { 
     276        String line = sc.nextLine(); 
     277        Scanner scline = new Scanner(line); 
     278 
     279        int loopID = scline.nextInt(); 
     280        int laneNum = scline.nextInt(); 
     281        String loopLoc = getLoopLoc(line); // NEED GET LOOPLOC 
     282        scline.close(); 
     283        return new LoopDetector(loopID, loopLoc, laneNum); 
     284    } 
     285 
     286    /** 
     287     * Scans the LoopDetector line and grabs the String location from the line. 
     288     *  
     289     * @param line the line containing the location 
     290     * @return A String loop location. 
     291     */ 
     292    private String getLoopLoc(String line) 
     293    { 
     294        Scanner sc = new Scanner(line); 
     295        sc.nextInt(); 
     296        sc.nextInt(); 
    250297 
    251298     // GRABS FROM CURRENT TO END OF LINE 
    252           
    253      sc.useDelimiter("\\z"); 
    254      String loc = sc.next().trim(); 
    255      sc.close(); 
    256      return loc; 
    257      } 
    258  
    259      // Returns the loction given the whole line from the lookup file 
    260      private String getStationLoc(String line) { 
    261      Scanner scline = new Scanner(line); 
    262      scline.nextInt(); 
    263      scline.nextInt(); 
    264      scline.nextInt(); 
    265      scline.next(); 
    266      scline.nextDouble(); 
    267      scline.nextInt(); 
    268  
    269      // GRABS FROM CURRENT TO END OF LINE 
    270      scline.useDelimiter("\\z"); 
    271      String loc = scline.next().trim(); 
    272      scline.close(); 
    273      return loc; 
    274      } 
    275      */ 
    276  
    277     public void writeToFEP() throws SimulationException { 
    278         try { 
    279             Socket sock = new Socket(FEPHostName /*"192.168.251.130"*/, 8080); 
     299        sc.useDelimiter("\\z"); 
     300        String loc = sc.next().trim(); 
     301        sc.close(); 
     302        return loc; 
     303    } 
     304 
     305    /** 
     306     * Scans the Station line and grabs the String location from the line. 
     307     *  
     308     * @param line the line containing the location 
     309     * @return A String station location. 
     310     */ 
     311    private String getStationLoc(String line) 
     312    { 
     313        Scanner scline = new Scanner(line); 
     314        scline.nextInt(); 
     315        scline.nextInt(); 
     316        scline.nextInt(); 
     317        scline.next(); 
     318        scline.nextDouble(); 
     319        scline.nextInt(); 
     320 
     321        // GRABS FROM CURRENT TO END OF LINE 
     322        scline.useDelimiter("\\z"); 
     323        String loc = scline.next().trim(); 
     324        scline.close(); 
     325        return loc; 
     326    } 
     327     
     328    /**  
     329     * Creates a socket client that writes the Highways data to the FEP Simulator. 
     330     *  
     331     * @throws SimulationException  
     332     */ 
     333    public void writeToFEP() throws SimulationException 
     334    { 
     335        try 
     336        { 
     337            // Create the socket to the FEP Simulator 
     338            Socket sock = new Socket(FEPHostName, FEPPortNum); 
    280339            PrintWriter out = new PrintWriter(sock.getOutputStream(), true); 
     340             
     341            // Print the number of bytes the highways data message contains 
    281342            System.out.println("BYTES: " + this.toXML().toCharArray().length + 1); 
     343             
     344            // Write the highways data over the socket 
    282345            out.println(this.toXML()); 
     346             
     347            // close the socket 
    283348            sock.close(); 
    284         } catch (IOException ex) { 
     349        } catch (IOException ex) 
     350        { 
    285351            Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); 
    286352            System.out.println("Highway Model failed writing to FEPSim."); 
    287353            throw new SimulationException(SimulationException.BINDING); 
    288354        } 
    289         updateSequences(); 
    290     } 
    291  
    292     // CHECK: DO WE EVEN NEED TO DO THIS? 
    293     private void updateSequences() { 
    294         for (FEPLine line : lines) { 
    295             line.updateSequences(); 
    296         } 
    297     } 
    298  
    299     /** 
    300      * Returns the network metadata in condensed form. This is just a quick 
    301      * script function to make a proper highway metadata configuration file, so 
    302      * that we can read the network faster. 
     355    } 
     356 
     357    /** 
     358     * Returns the highways metadata in condensed form. This function took the  
     359     * highways model and wrote it into condensed form. It is also useful for 
     360     * testing. 
    303361     * 
    304      * @return Network metadata 
    305      */ 
    306     public void writeHighwaysMeta(String fileName) { 
    307  
    308         try { 
    309             FileWriter fw = new FileWriter(new File(fileName)); 
     362     * @return the highways meta data string 
     363     */ 
     364    public String getHighwaysMeta() 
     365    { 
    310366            StringBuilder build = new StringBuilder(); 
    311367            build.append(lines.size()); 
    312368            build.append("\n"); 
    313             System.out.println(lines.size()); 
    314             fw.write(build.toString()); 
    315             int count = 1; 
    316             for (FEPLine line : lines) { 
    317                 System.out.println("Writing num: " + count); 
    318                 count++; 
    319                 fw.write(line.getLineMeta()); 
    320  
    321             } 
    322         } catch (IOException ex) { 
    323             Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); 
    324         } 
    325     } 
    326  
    327     public String toXML() { 
     369            for (FEPLine line : lines) 
     370            { 
     371                build.append(line.getLineMeta()); 
     372            } 
     373            return build.toString(); 
     374    } 
     375 
     376    /** 
     377     * Returns the Highways model data in XML format. 
     378     *  
     379     * @return highways data in XML format 
     380     */ 
     381    public String toXML() 
     382    { 
    328383        String xml = null; 
    329         try { 
     384        try 
     385        { 
    330386            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    331387            DocumentBuilder builder = factory.newDocumentBuilder(); 
     
    335391            theDoc.appendChild(networkElement); 
    336392 
    337             for (FEPLine line : lines) { 
     393            for (FEPLine line : lines) 
     394            { 
    338395                line.toXML(networkElement); 
    339396            } 
     
    349406            xml = out.toString(); 
    350407            out.close(); 
    351         } catch (Exception ex) { 
     408        } catch (Exception ex) 
     409        { 
    352410            Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex); 
    353411        } 
     
    356414    } 
    357415 
    358     public Highway getHighwayByRouteNumber(Integer routeNum) { 
     416    /** 
     417     * Returns a highway by given highway number. 
     418     *  
     419     * @param routeNum 
     420     * @return Highway with specified route number 
     421     */ 
     422    public Highway getHighwayByRouteNumber(Integer routeNum) 
     423    { 
    359424        Highway returnHwy = null; 
    360         for(Highway hwy : highways) 
    361         { 
    362             if(hwy.routeNumber.equals(routeNum)) 
     425        for (Highway hwy : highways) 
     426        { 
     427            if (hwy.routeNumber.equals(routeNum)) 
    363428            { 
    364429                returnHwy = hwy; 
     
    369434    } 
    370435 
    371     private static enum XML_TAGS { 
     436    /** 
     437     * XML tags used in writeToXML() 
     438     */ 
     439    private static enum XML_TAGS 
     440    { 
    372441 
    373442        NETWORK("Network"); 
     
    375444        String tag; 
    376445 
    377         private XML_TAGS(String n) { 
     446        private XML_TAGS(String n) 
     447        { 
    378448            tag = n; 
    379449        } 
Note: See TracChangeset for help on using the changeset viewer.