]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/threedee/ThreeDModel.java
7245633aa0667b936a0d5307fc8b0b84f2b38136
[GpsPrune.git] / tim / prune / threedee / ThreeDModel.java
1 package tim.prune.threedee;
2
3 import tim.prune.data.Altitude;
4 import tim.prune.data.DataPoint;
5 import tim.prune.data.PointScaler;
6 import tim.prune.data.Track;
7
8 /**
9  * Class to hold a 3d model of the track data,
10  * including all points and scaling operations.
11  * Used by java3d and also Pov export functions
12  */
13 public class ThreeDModel
14 {
15         private Track _track = null;
16         private PointScaler _scaler = null;
17         private double _modelSize;
18         private double _scaleFactor = 1.0;
19         private double _altFactor = 1.0;
20         // MAYBE: How to store rods (lifts) in data?
21         private byte[] _pointTypes = null;
22         private byte[] _pointHeights = null;
23
24         private static final double DEFAULT_MODEL_SIZE = 10.0;
25
26         // Constants for point types
27         public static final byte POINT_TYPE_WAYPOINT      = 1;
28         public static final byte POINT_TYPE_NORMAL_POINT  = 2;
29         public static final byte POINT_TYPE_SEGMENT_START = 3;
30
31
32         /**
33          * Constructor
34          * @param inTrack Track object
35          */
36         public ThreeDModel(Track inTrack)
37         {
38                 this(inTrack, DEFAULT_MODEL_SIZE);
39         }
40
41
42         /**
43          * Constructor
44          * @param inTrack Track object
45          * @param inSize model size
46          */
47         public ThreeDModel(Track inTrack, double inSize)
48         {
49                 _track = inTrack;
50                 _modelSize = inSize;
51                 if (_modelSize <= 0.0) _modelSize = DEFAULT_MODEL_SIZE;
52         }
53
54
55         /**
56          * @return the number of points in the model
57          */
58         public int getNumPoints()
59         {
60                 if (_track == null) return 0;
61                 return _track.getNumPoints();
62         }
63
64         /**
65          * @param inFactor altitude exaggeration factor (default 1.0)
66          */
67         public void setAltitudeFactor(double inFactor)
68         {
69                 if (inFactor >= 1.0) {
70                         _altFactor = inFactor;
71                 }
72         }
73
74         /**
75          * Scale all points and calculate factors
76          */
77         public void scale()
78         {
79                 // Use PointScaler to sort out x and y values
80                 _scaler = new PointScaler(_track);
81                 _scaler.scale();
82                 // Calculate scale factor to fit within box
83                 _scaleFactor = 1.0;
84                 if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
85                 {
86                         if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
87                         {
88                                 // scale limited by longitude
89                                 _scaleFactor = _modelSize / _scaler.getMaximumHoriz();
90                         }
91                         else
92                         {
93                                 // scale limited by latitude
94                                 _scaleFactor = _modelSize / _scaler.getMaximumVert();
95                         }
96                 }
97                 // cap altitude scale factor if it's too big
98                 double maxScaledAlt = _scaler.getMaxScaledAlt() * _altFactor;
99                 if (maxScaledAlt > _modelSize) {
100                         // capped
101                         _altFactor = _altFactor * _modelSize / maxScaledAlt;
102                 }
103                 // calculate lat/long lines
104                 _scaler.calculateLatLongLines();
105
106                 // calculate point types and height codes
107                 calculatePointTypes();
108         }
109
110
111         /**
112          * Calculate the point types and height codes
113          */
114         private void calculatePointTypes()
115         {
116                 int numPoints = getNumPoints();
117                 _pointTypes = new byte[numPoints];
118                 _pointHeights = new byte[numPoints];
119                 // Loop over points in track
120                 for (int i=0; i<numPoints; i++)
121                 {
122                         DataPoint point = _track.getPoint(i);
123                         _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
124                                 (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
125                         _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
126                 }
127         }
128
129
130         /**
131          * Get the scaled horizontal value for the specified point
132          * @param inIndex index of point
133          * @return scaled horizontal value
134          */
135         public double getScaledHorizValue(int inIndex)
136         {
137                 return _scaler.getHorizValue(inIndex) * _scaleFactor;
138         }
139
140         /**
141          * Get the scaled vertical value for the specified point
142          * @param inIndex index of point
143          * @return scaled vertical value
144          */
145         public double getScaledVertValue(int inIndex)
146         {
147                 return _scaler.getVertValue(inIndex) * _scaleFactor;
148         }
149
150         /**
151          * Get the scaled altitude value for the specified point
152          * @param inIndex index of point
153          * @return scaled altitude value
154          */
155         public double getScaledAltValue(int inIndex)
156         {
157                 // if no altitude, just return 0
158                 double altVal = _scaler.getAltValue(inIndex);
159                 if (altVal < 0) return 0;
160                 // scale according to exaggeration factor
161                 return altVal * _altFactor;
162         }
163
164
165         /**
166          * @return latitude lines
167          */
168         public double[] getLatitudeLines()
169         {
170                 return _scaler.getLatitudeLines();
171         }
172
173         /**
174          * @param inIndex index of line, starting at 0
175          * @return scaled position of latitude line
176          */
177         public double getScaledLatitudeLine(int inIndex)
178         {
179                 return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
180         }
181
182         /**
183          * @return longitude lines
184          */
185         public double[] getLongitudeLines()
186         {
187                 return _scaler.getLongitudeLines();
188         }
189
190         /**
191          * @param inIndex index of line, starting at 0
192          * @return scaled position of longitude line
193          */
194         public double getScaledLongitudeLine(int inIndex)
195         {
196                 return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
197         }
198
199         /**
200          * @param inIndex index of point, starting at 0
201          * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
202          */
203         public byte getPointType(int inIndex)
204         {
205                 return _pointTypes[inIndex];
206         }
207
208         /**
209          * @param inIndex index of point, starting at 0
210          * @return point height code
211          */
212         public byte getPointHeightCode(int inIndex)
213         {
214                 return _pointHeights[inIndex];
215         }
216
217         /**
218          * @return the current model size
219          */
220         public double getModelSize()
221         {
222                 return _modelSize;
223         }
224 }