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

source: tmcsimulator/trunk/src/atmsdriver/model/Station.java @ 184

Revision 184, 9.7 KB checked in by jtorres, 9 years ago (diff)

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

RevLine 
1package atmsdriver.model;
2
3import atmsdriver.model.LoopDetector.DOTCOLOR;
4import java.util.List;
5import org.w3c.dom.Document;
6import org.w3c.dom.Element;
7
8/**
9 * A Station (LDS or Loop Detector Station) represents a group of lane detectors
10 * across all lanes at a particular point on a highway.  A station is
11 * identified by its highway number and postmile.  A station has an associated
12 * direction used to establish which direction is Main and which is Opposite.
13 * The MLTotVol and OppTotVol for a station can be dynamically updated.
14 * A station has other attributes: lineNum, ldsID, drop, and location which are
15 * used by the FEP.  A station can be compared to other stations by its postmile.
16 *
17 * @author John A. Torres
18 * @version 9/10/2017
19 */
20public class Station implements Comparable
21{
22
23    /* Static Station meta data */
24    final public int lineNum;
25    final public int ldsID; // double check
26    final public int drop;
27    final public String location;
28    final public List<LoopDetector> loops;
29    final public int routeNumber;
30    final public double postmile;
31    final public DIRECTION direction;
32
33    /* Dynamic Station data */
34    private int MLTotVol;
35    private int OppTotVol;
36
37    /* Constructor */
38    public Station(int lineNum, int ldsID, int drop,
39            String location, List<LoopDetector> loops, int hwy,
40            DIRECTION direction, double postmile)
41    {
42        this.lineNum = lineNum;
43        this.ldsID = ldsID;
44        this.drop = drop;
45        this.loops = loops;
46        this.location = location;
47        this.postmile = postmile;
48        this.direction = direction;
49        this.routeNumber = hwy;
50
51        this.MLTotVol = getMLTotVol();
52        this.OppTotVol = getOPPTotVol();
53    }
54   
55    /**
56     * Calculates the total ML Volume.
57     *
58     * @return total ML volume.
59     */
60    private int getMLTotVol()
61    {
62        int mlTotVol = 0;
63        for(LoopDetector loop : loops)
64        {
65            if(loop.loopLocation.startsWith("ML"))
66            {
67                mlTotVol += loop.vol;
68            }
69        }
70        return mlTotVol;
71    }
72   
73    /**
74     * Calculates the total OPP Volume
75     *
76     * @return total OPP volume.
77     */
78    private int getOPPTotVol()
79    {
80        int oppTotVol = 0;
81        for(LoopDetector loop : loops)
82        {
83            if(loop.loopLocation.startsWith("OS"))
84            {
85                oppTotVol += loop.vol;
86            }
87        }
88        return oppTotVol;
89    }
90
91    /**
92     * Returns the station metadata in condensed form. This is just a quick
93     * script function to make a proper highway metadata configuration file, so
94     * that we can read the network faster.
95     *
96     * @return station metadata
97     */
98    public String getStationMeta()
99    {
100        StringBuilder build = new StringBuilder();
101        build.append(Integer.toString(this.ldsID));
102        build.append(" ");
103        build.append(Integer.toString(this.drop));
104        build.append(" ");
105        build.append(Integer.toString(this.routeNumber));
106        build.append(" ");
107        build.append(this.direction.getLetter());
108        build.append(" ");
109        build.append(Double.toString(this.postmile));
110        build.append(" ");
111        build.append(Integer.toString(loops.size()));
112        build.append(" ");
113        build.append(this.location);
114        build.append("\n");
115        for (LoopDetector loop : loops)
116        {
117            build.append(loop.getLoopMeta());
118        }
119        return build.toString();
120    }
121
122    /**
123     * Compare this Station to another by postmile. Note: This might be better
124     * as a Comparator since it checks only one field.
125     */
126    @Override
127    public int compareTo(Object otherStation)
128    {
129        // check for identity
130        if (this == otherStation)
131        {
132            return 0;
133        }
134        // check that Object is of type Station, if not throw exception
135        if (!(otherStation instanceof Station))
136        {
137            throw new ClassCastException("A Station object expected.");
138        }
139
140        // get difference of values
141        double otherStationPostmile = ((Station) otherStation).postmile;
142        double val = this.postmile - otherStationPostmile;
143
144        // set appropriate comparable return value
145        int retval = 0;
146        if (val > 0)
147        {
148            retval = 1;
149        }
150        else if (val < 0)
151        {
152            retval = -1;
153        }
154
155        return retval;
156    }
157
158    /** Determine which lane fields to update based on given direction
159     * and update all the loop detectors with the given color.
160     * @param direction desired highway direction
161     * @param dotColor desired dot color
162     */
163    public void updateByDirection(DIRECTION direction, DOTCOLOR dotColor) 
164    {
165        String laneDir = "OS";
166        if(direction.equals(this.direction))
167        {
168            laneDir = "ML";
169        }
170        outputUpdateMessage(dotColor, laneDir);
171       
172        for(LoopDetector loop : loops)
173        {
174            if(loop.loopLocation.startsWith(laneDir))
175            {
176                // UPDATE LOOP WITH VALUES
177                int speed = 0;
178                loop.updateLoop(dotColor.volume(), dotColor.occupancy(), speed);
179            }
180        }
181       
182        this.MLTotVol = getMLTotVol();
183        this.OppTotVol = getOPPTotVol();
184    }
185   
186    /**
187     * Output for updateByDirection. Logs the update to the console.
188     *
189     * @param dotcolor
190     * @param OPP_ML
191     */
192    private void outputUpdateMessage(DOTCOLOR dotcolor, String OPP_ML)
193    {
194        System.out.printf("Updating %-3.3s %-5.5s %-3.3s lanes\t %-12.12s "
195                + "at postmile %-6.6s to %-7.7s\n", 
196                Integer.toString(this.routeNumber), this.direction.name(), 
197                OPP_ML, this.location, Double.toString(this.postmile), 
198                dotcolor.name());
199    }
200   
201    /**
202     * XML tags used for toXML() method.
203     */
204    private static enum XML_TAGS
205    {
206
207        STATION("Station"),
208        LDS_ID("LDS_ID"),
209        LINE_NUM("Line_Num"),
210        DROP("Drop"),
211        LOOPS("Loops"),
212        LOCATION("Location"),
213        POST_MILE("Post_Mile"),
214        DIRECTION("Direction"),
215        FREEWAY("Freeway"),
216        ML_TOT_VOL("ML_Tot_Vol"),
217        OPP_TOT_VOL("Opp_Tot_Vol");
218
219        String tag;
220
221        private XML_TAGS(String n)
222        {
223            tag = n;
224        }
225    }
226   
227    /**
228     * Returns the Station data in XMLFormat.
229     *
230     * @param currElem The current XML <Station> element
231     */
232    public void toXML(Element currElem)
233    {
234        Document theDoc = currElem.getOwnerDocument();
235
236        Element stationElement = theDoc.createElement(XML_TAGS.STATION.tag);
237        currElem.appendChild(stationElement);
238
239        Element ldsIDElement = theDoc.createElement(XML_TAGS.LDS_ID.tag);
240        ldsIDElement.appendChild(theDoc.createTextNode(String.valueOf(this.ldsID)));
241        stationElement.appendChild(ldsIDElement);
242
243        Element lineNumElement = theDoc.createElement(XML_TAGS.LINE_NUM.tag);
244        lineNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineNum)));
245        stationElement.appendChild(lineNumElement);
246
247        Element dropElement = theDoc.createElement(XML_TAGS.DROP.tag);
248        dropElement.appendChild(theDoc.createTextNode(String.valueOf(this.drop)));
249        stationElement.appendChild(dropElement);
250
251        Element locationElement = theDoc.createElement(XML_TAGS.LOCATION.tag);
252        locationElement.appendChild(theDoc.createTextNode(this.location));
253        stationElement.appendChild(locationElement);
254
255        Element postMileElement = theDoc.createElement(XML_TAGS.POST_MILE.tag);
256        postMileElement.appendChild(theDoc.createTextNode(String.valueOf(this.postmile)));
257        stationElement.appendChild(postMileElement);
258
259        Element directionElement = theDoc.createElement(XML_TAGS.DIRECTION.tag);
260        directionElement.appendChild(theDoc.createTextNode("" + this.direction.getLetter()));
261        stationElement.appendChild(directionElement);
262
263        Element freewayElement = theDoc.createElement(XML_TAGS.FREEWAY.tag);
264        freewayElement.appendChild(theDoc.createTextNode(String.valueOf(this.routeNumber)));
265        stationElement.appendChild(freewayElement);
266
267        Element mlElement = theDoc.createElement(XML_TAGS.ML_TOT_VOL.tag);
268        mlElement.appendChild(theDoc.createTextNode(String.valueOf(this.MLTotVol)));
269        stationElement.appendChild(mlElement);
270
271        Element oppElement = theDoc.createElement(XML_TAGS.OPP_TOT_VOL.tag);
272        oppElement.appendChild(theDoc.createTextNode(String.valueOf(this.OppTotVol)));
273        stationElement.appendChild(oppElement);
274
275        Element loopsElement = theDoc.createElement(XML_TAGS.LOOPS.tag);
276        stationElement.appendChild(loopsElement);
277
278        for (LoopDetector loop : loops)
279        {
280            loop.toXML(loopsElement);
281        }
282    }
283
284    /**
285     * Enum for freeway direction.
286     *
287     * @author John A. Torres
288     * @version 9/10/2017
289     */
290    public static enum DIRECTION
291    {
292        NORTH,
293        SOUTH,
294        EAST,
295        WEST;
296
297        // All the first letters of the values, in order.
298        private static String allLetters = "NSEW";
299
300        /**
301         * Return the first letter of this enum.
302         *
303         * @return String first letter of this enum.
304         */
305        public String getLetter()
306        {
307            return this.toString().substring(0, 1);
308        }
309
310        /**
311         * Returns a direction given its first character.
312         *
313         * @param letter the first character of a direction
314         * @return direction corresponding to letter
315         * @pre letter must be one of allLetters
316         */
317        public static DIRECTION toDirection(String letter)
318        {
319            return values()[allLetters.indexOf(letter.charAt(0))];
320        }
321
322    }
323}
Note: See TracBrowser for help on using the repository browser.