package atmsdriver.model; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * A Station is a simulation of a station in a traffic network. * * A Station (LDS) contains static meta data about the station, and two dynamic * attributes, MLTotVol and OppTotVol. * * A single LDS contains multiple LoopDetectors, which contain data for a single * lane on one direction of the freeway. A LDS is specific to a single freeway, * direction, and postmile. * * @author John A. Torres * @version 9/10/2017 */ public class Station implements Comparable { /* Static Station meta data */ final private int lineNum; final private int ldsID; // double check final private int drop; final private String location; final private List loops; final private int freeway; final private double postmile; final private DIRECTION direction; /* Dynamic Station data */ private int MLTotVol; private int OppTotVol; /* Constructor */ public Station(int lineNum, int ldsID, int drop, String location, List loops, int fwy, DIRECTION direction, double postmile) { this.lineNum = lineNum; this.ldsID = ldsID; this.drop = drop; this.loops = loops; this.location = location; this.postmile = postmile; this.direction = direction; this.freeway = fwy; this.MLTotVol = 0; this.OppTotVol = 0; } public int getHighwayNumber() { return this.freeway; } public DIRECTION getDirection() { return this.direction; } /** * Returns the station metadata in condensed form. This is just a quick * script function to make a proper highway metadata configuration file, so * that we can read the network faster. * * @return station metadata */ public String getStationMeta() { StringBuilder build = new StringBuilder(); build.append(Integer.toString(this.ldsID)); build.append(" "); build.append(Integer.toString(this.drop)); build.append(" "); build.append(Integer.toString(this.freeway)); build.append(" "); build.append(this.direction.name); build.append(" "); build.append(Double.toString(this.postmile)); build.append(" "); build.append(Integer.toString(loops.size())); build.append(" "); build.append(this.location); build.append("\n"); for (LoopDetector loop : loops) { build.append(loop.getLoopMeta()); } return build.toString(); } public double getPostmile() { return postmile; } @Override public int compareTo(Object otherStation) { // check that Object is of type Station, if not throw exception if (!(otherStation instanceof Station)) { throw new ClassCastException("A Station object expected."); } // get difference of values double otherStationPostmile = ((Station) otherStation).getPostmile(); double val = this.postmile - otherStationPostmile; // set appropriate comparable return value int retval = 0; if (val > 0) { retval = 1; } else if (val < 0) { retval = -1; } return retval; } private static enum XML_TAGS { STATION("Station"), LDS_ID("LDS_ID"), LINE_NUM("Line_Num"), DROP("Drop"), LOOPS("Loops"), LOCATION("Location"), POST_MILE("Post_Mile"), DIRECTION("Direction"), FREEWAY("Freeway"), ML_TOT_VOL("ML_Tot_Vol"), OPP_TOT_VOL("Opp_Tot_Vol"); String tag; private XML_TAGS(String n) { tag = n; } } public void toXML(Element currElem) { Document theDoc = currElem.getOwnerDocument(); Element stationElement = theDoc.createElement(XML_TAGS.STATION.tag); currElem.appendChild(stationElement); Element ldsIDElement = theDoc.createElement(XML_TAGS.LDS_ID.tag); ldsIDElement.appendChild(theDoc.createTextNode(String.valueOf(this.ldsID))); stationElement.appendChild(ldsIDElement); Element lineNumElement = theDoc.createElement(XML_TAGS.LINE_NUM.tag); lineNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineNum))); stationElement.appendChild(lineNumElement); Element dropElement = theDoc.createElement(XML_TAGS.DROP.tag); dropElement.appendChild(theDoc.createTextNode(String.valueOf(this.drop))); stationElement.appendChild(dropElement); Element locationElement = theDoc.createElement(XML_TAGS.LOCATION.tag); locationElement.appendChild(theDoc.createTextNode(this.location)); stationElement.appendChild(locationElement); Element postMileElement = theDoc.createElement(XML_TAGS.POST_MILE.tag); postMileElement.appendChild(theDoc.createTextNode(String.valueOf(this.postmile))); stationElement.appendChild(postMileElement); Element directionElement = theDoc.createElement(XML_TAGS.DIRECTION.tag); directionElement.appendChild(theDoc.createTextNode(this.direction.name)); stationElement.appendChild(directionElement); Element freewayElement = theDoc.createElement(XML_TAGS.FREEWAY.tag); freewayElement.appendChild(theDoc.createTextNode(String.valueOf(this.freeway))); stationElement.appendChild(freewayElement); Element mlElement = theDoc.createElement(XML_TAGS.ML_TOT_VOL.tag); mlElement.appendChild(theDoc.createTextNode(String.valueOf(this.MLTotVol))); stationElement.appendChild(mlElement); Element oppElement = theDoc.createElement(XML_TAGS.OPP_TOT_VOL.tag); oppElement.appendChild(theDoc.createTextNode(String.valueOf(this.OppTotVol))); stationElement.appendChild(oppElement); Element loopsElement = theDoc.createElement(XML_TAGS.LOOPS.tag); stationElement.appendChild(loopsElement); for (LoopDetector loop : loops) { loop.toXML(loopsElement); } } /** * Enum for freeway direction. * * @author John A. Torres * @version 9/10/2017 */ public static enum DIRECTION { NORTH("N"), SOUTH("S"), EAST("E"), WEST("W"); String name; DIRECTION(String name) { this.name = name; } /** * Returns the direction enum, given a string value. * * @param name str value for enum * @return enum for given str value */ public static DIRECTION getEnum(String name) { switch (name) { case "S": return SOUTH; case "N": return NORTH; case "E": return EAST; case "W": return WEST; default: return null; } } } }