Warning: Can't use blame annotator:
svn blame failed on trunk/src/atmsdriver/model/Highways.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/src/atmsdriver/model/Highways.java @ 180

Revision 180, 12.8 KB checked in by jdalbey, 9 years ago (diff)

ATMSDriver.java Refactored for cleaner design. DotColor? enum moved to LoopDetector? class. ConsoleDriver? renamed ConsoleTrafficDriver? (and associated project configurations updated), build.xml package-jars target updated, ConsoleTrafficDriver? logic improved to allow more user control, runtraffic.bash script created for automating traffic display tests.

RevLine 
1package atmsdriver.model;
2
3import atmsdriver.FEPLineLoader;
4import java.io.File;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.io.PrintWriter;
8import java.io.StringWriter;
9import java.io.Writer;
10import java.net.Socket;
11import java.util.ArrayList;
12import java.util.Collections;
13import java.util.HashMap;
14import java.util.Map;
15import java.util.Observable;
16import java.util.Observer;
17import java.util.Set;
18import java.util.logging.Level;
19import java.util.logging.Logger;
20import javax.xml.parsers.DocumentBuilder;
21import javax.xml.parsers.DocumentBuilderFactory;
22import javax.xml.transform.OutputKeys;
23import javax.xml.transform.Transformer;
24import javax.xml.transform.TransformerFactory;
25import javax.xml.transform.dom.DOMSource;
26import javax.xml.transform.stream.StreamResult;
27import org.w3c.dom.Document;
28import org.w3c.dom.Element;
29import tmcsim.common.SimulationException;
30
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.
45 *
46 * @author John A. Torres
47 */
48public class Highways {
49
50    final private ArrayList<FEPLine> lines;
51    final private String FEPHostName;
52    final private int FEPPortNum;
53   
54    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();
65        this.FEPHostName = FEPHostName;
66        this.FEPPortNum = FEPPortNum;
67        this.highways = loadHighways();
68        //writeHighwaysMeta("hard.txt");
69    }
70   
71    private ArrayList<Highway> loadHighways() {
72        System.out.println("Loading highways...");
73        // The list of highways to return
74        ArrayList<Highway> highways = new ArrayList<Highway>();
75       
76        Map<Integer, ArrayList<Station>>
77                highwayMap = new HashMap<>();
78       
79        for (FEPLine line : lines)
80        {
81            ArrayList<Station> lineStations = (ArrayList<Station>) line.stations;
82            for(Station station : lineStations)
83            {
84                Integer hwyNum = station.routeNumber;
85
86                if(!highwayMap.containsKey(hwyNum))
87                {
88                    ArrayList<Station> stnList = new ArrayList<>();
89                    stnList.add(station);
90                    highwayMap.put(hwyNum, stnList);
91                }
92                else
93                {
94                    highwayMap.get(hwyNum).add(station);
95                }
96            }
97        }
98       
99        Set<Integer> hwyKeys = highwayMap.keySet();
100        for(Integer hwyKey : hwyKeys)
101        {
102            ArrayList<Station> hwyStations = highwayMap.get(hwyKey);
103            Collections.sort(hwyStations);
104            System.out.println("Loaded highway " + hwyKey + "...");
105            highways.add(new Highway(hwyKey, 
106                    hwyStations));
107        }
108        System.out.println("");
109        return highways;
110    }
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     *
116     * @param routeNumber highway route number
117     * @param direction highway direction
118     * @param postmile origin postmile value
119     * @param range range from origin postmile
120     * @param dotColor the color to be applied to specified highway stretch
121     */
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 " 
126                + postmile + " with a range of " + range + " miles...");
127       
128        // Get the highway by route number
129        Highway highway = getHighwayByRouteNumber(routeNumber);
130       
131        // start value for highway section, and end value for highway section
132        // by postmile
133        Double startPost;
134        Double endPost;
135       
136        // postmiles increase from s to n and w to e
137       
138        // if the direction is south or west
139        if(direction.equals(Station.DIRECTION.SOUTH) || direction.equals(Station.DIRECTION.WEST))
140        {
141            // add range value to startPost to get
142            // the end postmile value of the highway section
143            startPost = postmile;
144            endPost = postmile + range;
145           
146            // iterate through the stations, if within the specified highway
147            // 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)
151                {
152                    station.updateByDirection(direction, dotColor);
153                }
154            }
155        }
156        // if the direction is north or east
157        else
158        {
159            //subtract range value from startPost
160            // to get the end postmile value of the highway section
161            startPost = postmile;
162            endPost = postmile - range;
163           
164            // iterate through the stations, if within the specified highway
165            // 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)
169                {
170                    station.updateByDirection(direction, dotColor);
171                }
172            }
173        }
174        System.out.println("");
175    }
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();
250
251     // 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);
280            PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
281            System.out.println("BYTES: " + this.toXML().toCharArray().length + 1);
282            out.println(this.toXML());
283            sock.close();
284        } catch (IOException ex) {
285            Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex);
286            System.out.println("Highway Model failed writing to FEPSim.");
287            throw new SimulationException(SimulationException.BINDING);
288        }
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.
303     *
304     * @return Network metadata
305     */
306    public void writeHighwaysMeta(String fileName) {
307
308        try {
309            FileWriter fw = new FileWriter(new File(fileName));
310            StringBuilder build = new StringBuilder();
311            build.append(lines.size());
312            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() {
328        String xml = null;
329        try {
330            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
331            DocumentBuilder builder = factory.newDocumentBuilder();
332            Document theDoc = builder.newDocument();
333
334            Element networkElement = theDoc.createElement(XML_TAGS.NETWORK.tag);
335            theDoc.appendChild(networkElement);
336
337            for (FEPLine line : lines) {
338                line.toXML(networkElement);
339            }
340
341            Transformer tf = TransformerFactory.newInstance().newTransformer();
342
343            tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
344            tf.setOutputProperty(OutputKeys.INDENT, "yes");
345            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
346
347            Writer out = new StringWriter();
348            tf.transform(new DOMSource(theDoc), new StreamResult(out));
349            xml = out.toString();
350            out.close();
351        } catch (Exception ex) {
352            Logger.getLogger(Highways.class.getName()).log(Level.SEVERE, null, ex);
353        }
354        return xml;
355
356    }
357
358    public Highway getHighwayByRouteNumber(Integer routeNum) {
359        Highway returnHwy = null;
360        for(Highway hwy : highways)
361        {
362            if(hwy.routeNumber.equals(routeNum))
363            {
364                returnHwy = hwy;
365                break;
366            }
367        }
368        return returnHwy;
369    }
370
371    private static enum XML_TAGS {
372
373        NETWORK("Network");
374
375        String tag;
376
377        private XML_TAGS(String n) {
378            tag = n;
379        }
380    }
381}
Note: See TracBrowser for help on using the repository browser.