1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """
22 Co-ordinate the generation of profiles for a rideset.
23 """
24 from sabx10.oxm import parse_no_def_namespaces, meter_feet, process_rides
25
26 from consts import PROFILE_PPI, PROFILE_PDF_PPI
27 from plotter import ProfilePlotter
28
30 """
31 Convert an elevation from meters to feet.
32
33 @param ele: elevation to convert
34 @type ele: C{float}
35
36 @return: elevation in feet
37 @rtype: C{float}
38 """
39 return (ele * meter_feet)
40
42 """
43 For a list of points representing a line, generate lists of the elevations
44 and distances along the line for each point.
45
46 @param points: points to process
47 @type points: C{list} of L{Point}
48 @param length: length of line the points represent
49 @type length: C{float}
50
51 @return: distances list, elevations list
52 @rtype: (C{list} of C{float},C{list} of C{float})
53 """
54 dist = 0.0
55 distances = []
56 elevations = []
57
58 for index in range(len(points)-1):
59 elevation = _calc_elevation(points[index].ele)
60 distance = points[index].calculate_distance(points[index+1])
61
62 elevations.append(elevation)
63 distances.append(dist)
64
65 dist += distance
66
67 distances.append(length)
68 elevations.append(_calc_elevation(points[-1].ele))
69
70 return distances, elevations
71
73 """
74 Plot a large and a small profile for each segment in a list. These profiles
75 are not annotated.
76
77 @param plotter: L{ProfilePlotter} to generate the plots
78 @type plotter: L{ProfilePlotter}
79 @param segs: C{list} of L{Segment}s to process
80 @type segs: C{list} of L{Segment} objects
81 """
82 for seg in segs:
83 distances, elevations = _process_points(seg.waypoints, seg.length)
84 plotter.plot_large_profile(distances, elevations, seg.length, seg.index)
85 plotter.plot_small_profile(distances, elevations, seg.length, seg.index)
86
88 """
89 Hold all information necessary for a profile annotation.
90
91 @ivar text: text of annotation
92 @type text: C{string}
93 @ivar dist: distance into ride of annotation (X value)
94 @type dist: C{float}
95 @ivar ele: elevation of annotation (Y value)
96 @type ele: C{float}
97 """
99 """
100 Save the passed-in values.
101
102 @param text: text of annotation
103 @type text: C{string}
104 @param dist: distance into ride of annotation (X value)
105 @type dist: C{float}
106 @param ele: elevation of annotation (Y value)
107 @type ele: C{float}
108 """
109 self.text = text
110 self.dist = dist
111 self.ele = ele
112
114 """
115 Generate the annotations for a list of segments.
116
117 @param segs: C{list} of L{Segment}s to process
118 @type segs: C{list} of L{Segment} objects
119
120 @return: list of L{Annotation} objects
121 @rtype: C{list} of L{Annotation} objects
122 """
123 return [Annotation("%s-%s" % (seg.index,
124 seg.road.split('/')[0][:20]),
125 seg.start_dist,
126 _calc_elevation(seg.waypoints[0].ele))
127 for seg in segs]
128
149
151 """
152 Generate profiles for all the rides in a rideset, and all the rides'
153 segments as well (if asked).
154
155 @param xml_tree: C{ElementTree} representation of a rideset
156 @type xml_tree: C{ElementTree} stuff
157 @param graph_filebase: base filename for profile plots
158 @type graph_filebase: C{string}
159 @param graph_dir: directory to place profile plots into
160 @type graph_dir: C{string}
161 @param hires: high resolution?
162 @type hires: C{boolean}
163 @param segs: plot segments?
164 @type segs: C{boolean}
165 """
166 if hires:
167 ppi = PROFILE_PDF_PPI
168 else:
169 ppi = PROFILE_PPI
170
171 ride_list, bounds = process_rides(xml_tree)
172 for ride in ride_list:
173 plotter = ProfilePlotter(ride, graph_filebase, graph_dir, ppi)
174 if segs:
175 _process_segs(plotter, ride.segs)
176 _process_ride(plotter, ride)
177