001    package ps2;
002    
003    import java.util.*;
004    
005    
006    /**
007     * <p>
008     * A GeoFeature represents a path from one location to another along
009     * a single geographic feature.  GeoFeatures are immutable.
010     * </p>
011     *
012     * <p>
013     * GeoFeature abstracts over a sequence of GeoSegments, all of which
014     * have the same name, thus providing a representation for nonlinear
015     * or nonatomic geographic features.  As an example, a GeoFeature
016     * might represent the course of a winding river, or travel along a
017     * road through intersections but remaining on the same road.
018     * </p>
019     *
020     * <p>
021     * GeoFeatures are immutable.  New GeoFeatures can be constructed by
022     * adding a segment to the end of a GeoFeature.  An added segment must
023     * be properly oriented; that is, its p1 field must correspond to the
024     * end of the original GeoFeature, and its p2 field corresponds to the
025     * end of the new GeoFeature, and the name of the GeoSegment being
026     * added must match the name of the existing GeoFeature.
027     * </p>
028     *
029     * <p>
030     * Because a GeoFeature is not necessarily straight, its length -- the
031     * distance traveled by following the path from start to end -- is not
032     * necessarily the same as the distance along a straight line between
033     * its endpoints.
034     * </p>
035     *
036     * @specfield start : GeoPoint         // location of the start of the geo feature
037     * @specfield end : GeoPoint           // location of the end of the geo feature
038     * @specfield startHeading : angle     // direction of travel at the start of the geo feature, in degrees
039     * @specfield endHeading : angle       // direction of travel at the end of the geo feature, in degrees
040     * @specfield geoSegments : sequence   // a sequence of segments that make up this geographic feature
041     * @specfield name : String            // name of geographical feature
042     * @derivedfield length : real         // total length of the geo feature, in miles
043     *
044     **/
045    public class GeoFeature {
046    
047        //FIELDS
048    
049    
050        // Constructors
051    
052        /**
053         * Constructs a new GeoFeature.
054         * @requires gs != null
055         * @effects Constructs a new GeoFeature, r, such that
056         *          r.name = gs.name &&
057         *          r.startHeading = gs.heading &&
058         *          r.endHeading = gs.heading &&
059         *          r.start = gs.p1 &&
060         *          r.end = gs.p2
061         **/
062        public GeoFeature(GeoSegment gs) {
063            throw new RuntimeException("Not yet implemented");
064        }
065    
066    
067        /**
068         * Checks that the representation invariant holds (if any).
069         **/
070        // Throws a RuntimeException if the rep invariant is violated.
071        private void checkRep() throws RuntimeException {
072            throw new RuntimeException("Not yet implemented");
073        }
074    
075    
076        // Observers
077    
078        /**
079         * @return name of geographic feature
080         **/
081        public String getName() {
082            throw new RuntimeException("Not yet implemented");
083        }
084    
085    
086        /**
087         * @return location of the start of the feature
088         **/
089        public GeoPoint getStart() {
090            throw new RuntimeException("Not yet implemented");
091        }
092    
093    
094        /**
095         * @return location of the end of of the feature
096         **/
097        public GeoPoint getEnd() {
098            throw new RuntimeException("Not yet implemented");
099        }
100    
101    
102        /**
103         * @return direction (in standard heading) of travel at the start
104         * of the feature, in degrees
105         **/
106        public double getStartHeading() {
107            throw new RuntimeException("Not yet implemented");
108        }
109    
110    
111        /**
112         * @return direction of travel at the end of the feature, in
113         * degrees
114         **/
115        public double getEndHeading() {
116            throw new RuntimeException("Not yet implemented");
117        }
118    
119    
120        /**
121         * @return total length of the geo feature, in miles.  NOTE: this
122         * is NOT as-the-crow-flies, but rather the total distance
123         * required to traverse the geo feature.  These values are not
124         * necessarily equal.
125         **/
126        public double getLength() {
127            throw new RuntimeException("Not yet implemented");
128        }
129    
130    
131        // Producers
132    
133        /**
134         * Creates a new GeoFeature that is equal to this GeoFeature with
135         * gs appended to its end.
136         *
137         * @requires gs != null && gs.p1 = this.end && gs.name = this.name
138         * @return a new GeoFeature r such that
139         *       r.end = gs.p2
140         *    && r.endHeading = gs.heading
141         *    && r.length = this.length + gs.length
142         **/
143        public GeoFeature addSegment(GeoSegment gs) {
144            throw new RuntimeException("Not yet implemented");
145        }
146    
147    
148        // Observers
149    
150        /**
151         * Returns a List of GeoSegment objects.  The concatentation
152         * of the GeoSegments, in order, is equivalent to this GeoFeature.
153         * All the GeoSegments should have the same name.
154         * @return a List of GeoSegments such that
155         * <pre>
156         *      this.start        = a.get(0).p1
157         *   && this.startHeading = a.get(0).heading
158         *   && this.end          = a.get(a.size - 1).p2
159         *   && this.endHeading   = a.get(a.size - 1).heading
160         *   && this.length       =  sum (0 &lt;= i &lt; a.size) . a.get(i).length
161         *   && for all integers i .
162         *          (0 &lt;= i &lt; a.size - 1 =&gt; (a.get(i).name = a.get(i+1).name &&
163         *                                              a.get(i).p2 = a.get(i+1).p1))
164         * </pre>
165         * @see ps2.GeoSegment
166         */
167        public List<GeoSegment> getGeoSegments() {
168            throw new RuntimeException("Not yet implemented");
169        }
170    
171    
172        /**
173         * Compares the argument with this GeoFeature for equality.
174         * @return o != null && (o instanceof GeoFeature)
175         *         && (o.geoSegments and this.geoSegments contain
176         *             the same elements in the same order).
177         **/
178        public boolean equals(Object o) {
179            throw new RuntimeException("Not yet implemented");
180        }
181    
182    
183        /**
184         * @return a valid hashcode for this.
185         **/
186        public int hashCode() {
187            // This implementation will work, but you may want to modify
188            // it later for improved performance.  If you do change the
189            // implementation, make sure it satisfies the hashCode
190            // invariant.  That is, if equals returns true for two
191            // objects, then they must have the same hashCode.
192    
193            return (1);
194        }
195    
196    
197        /**
198         * @return a string representation of this.
199         **/
200        public String toString() {
201            throw new RuntimeException("Not yet implemented");
202        }
203    
204    } // GeoFeature