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         * This is the heading of the first non-zero-length segment.
106         **/
107        public double getStartHeading() {
108            throw new RuntimeException("Not yet implemented");
109        }
110    
111    
112        /**
113         * @return direction of travel at the end of the feature, in
114         * degrees.
115         * This is the heading of the last non-zero-length segment.
116         **/
117        public double getEndHeading() {
118            throw new RuntimeException("Not yet implemented");
119        }
120    
121    
122        /**
123         * @return total length of the geo feature, in miles.  NOTE: this
124         * is NOT as-the-crow-flies, but rather the total distance
125         * required to traverse the geo feature.  These values are not
126         * necessarily equal.
127         **/
128        public double getLength() {
129            throw new RuntimeException("Not yet implemented");
130        }
131    
132    
133        // Producers
134    
135        /**
136         * Creates a new GeoFeature that is equal to this GeoFeature with
137         * gs appended to its end.
138         *
139         * @requires gs != null && gs.p1 = this.end && gs.name = this.name
140         * @return a new GeoFeature r such that
141         *       r.end = gs.p2
142         *    && r.endHeading = gs.heading
143         *    && r.length = this.length + gs.length
144         **/
145        public GeoFeature addSegment(GeoSegment gs) {
146            throw new RuntimeException("Not yet implemented");
147        }
148    
149    
150        // Observers
151    
152        /**
153         * Returns a List of GeoSegment objects.  The concatenation
154         * of the GeoSegments, in order, is equivalent to this GeoFeature.
155         * All the GeoSegments should have the same name.
156         * @return a List of GeoSegments such that
157         * <pre>
158         *      this.start        = a.get(0).p1
159         *   && this.startHeading = a.get(0).heading
160         *   && this.end          = a.get(a.size - 1).p2
161         *   && this.endHeading   = a.get(a.size - 1).heading
162         *   && this.length       =  sum (0 &le; i &lt; a.size) . a.get(i).length
163         *   && for all integers i .
164         *          (0 &le; i &lt; a.size - 1 &rArr; (a.get(i).name = a.get(i+1).name &&
165         *                                              a.get(i).p2 = a.get(i+1).p1))
166         * </pre>
167         * @see ps2.GeoSegment
168         */
169        public List<GeoSegment> getGeoSegments() {
170            throw new RuntimeException("Not yet implemented");
171        }
172    
173    
174        /**
175         * Compares the argument with this GeoFeature for equality.
176         * @return o != null && (o instanceof GeoFeature)
177         *         && (o.geoSegments and this.geoSegments contain
178         *             the same elements in the same order).
179         **/
180        public boolean equals(Object o) {
181            throw new RuntimeException("Not yet implemented");
182        }
183    
184    
185        /**
186         * @return a valid hashcode for this.
187         **/
188        public int hashCode() {
189            // This implementation will work, but you may want to modify
190            // it later for improved performance.  If you do change the
191            // implementation, make sure it satisfies the hashCode
192            // invariant.  That is, if equals returns true for two
193            // objects, then they must have the same hashCode.
194    
195            return (1);
196        }
197    
198    
199        /**
200         * @return a string representation of this.
201         **/
202        public String toString() {
203            throw new RuntimeException("Not yet implemented");
204        }
205    
206    } // GeoFeature