Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/supersegments.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show annotations) (download) (as text)
Tue Jan 6 18:32:27 2009 UTC (16 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 8117 byte(s)
Initial revision

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/supersegments.c,v 1.1 2009-01-06 18:32:27 amb Exp $
3
4 Super-Segment data type functions.
5 ******************/ /******************
6 Written by Andrew M. Bishop
7
8 This file Copyright 2008,2009 Andrew M. Bishop
9 It may be distributed under the GNU Public License, version 2, or
10 any higher version. See section COPYING of the GNU Public license
11 for conditions under which this file may be redistributed.
12 ***************************************/
13
14
15 #include <assert.h>
16 #include <math.h>
17 #include <stdlib.h>
18
19 #include "functions.h"
20 #include "types.h"
21
22 #define INCREMENT 64*1024
23
24 /*+ The list of super-segments +*/
25 SuperSegments *OSMSuperSegments=NULL;
26
27 /*+ Is the data sorted and therefore searchable? +*/
28 static int sorted=0;
29
30 /*+ Is the data loaded from a file and therefore read-only? +*/
31 static int loaded=0;
32
33 /*+ How many entries are allocated? +*/
34 static size_t alloced=0;
35
36 /* Functions */
37
38 static void append_super_segment(node_t node1,node_t node2);
39 static int sort_by_id(SuperSegment *a,SuperSegment *b);
40
41
42 /*++++++++++++++++++++++++++++++++++++++
43 Load in a super-segment list from a file.
44
45 const char *filename The name of the file to load.
46 ++++++++++++++++++++++++++++++++++++++*/
47
48 void LoadSuperSegmentList(const char *filename)
49 {
50 assert(!OSMSuperSegments); /* Must be NULL */
51
52 OSMSuperSegments=(SuperSegments*)MapFile(filename);
53
54 assert(OSMSuperSegments); /* Must be non-NULL */
55
56 sorted=1;
57 loaded=1;
58 }
59
60
61 /*++++++++++++++++++++++++++++++++++++++
62 Save the super-segment list to a file.
63
64 const char *filename The name of the file to save.
65 ++++++++++++++++++++++++++++++++++++++*/
66
67 void SaveSuperSegmentList(const char *filename)
68 {
69 int retval;
70
71 assert(!loaded); /* Must not be loaded */
72
73 assert(sorted); /* Must be sorted */
74
75 retval=WriteFile(filename,OSMSuperSegments,sizeof(SuperSegments)-sizeof(OSMSuperSegments->segments)+OSMSuperSegments->number*sizeof(SuperSegment));
76
77 assert(!retval); /* Must be zero */
78 }
79
80
81 /*++++++++++++++++++++++++++++++++++++++
82 Find the first super-segment with a particular starting node.
83
84 SuperSegment *FindFirstSuperSegment Returns a pointer to the first super-segment with the specified id.
85
86 node_t node The node to look for.
87 ++++++++++++++++++++++++++++++++++++++*/
88
89 SuperSegment *FindFirstSuperSegment(node_t node)
90 {
91 int start=0;
92 int end=OSMSuperSegments->number-1;
93 int mid;
94 int found;
95
96 assert(sorted); /* Must be sorted */
97
98 /* Binary search - search key exact match only is required.
99 *
100 * # <- start | Check mid and move start or end if it doesn't match
101 * # |
102 * # | Since an exact match is wanted we can set end=mid-1
103 * # <- mid | or start=mid+1 because we know that mid doesn't match.
104 * # |
105 * # | Eventually either end=start or end=start+1 and one of
106 * # <- end | start or end is the wanted one.
107 */
108
109 if(OSMSuperSegments->number==0) /* There are no segments */
110 return(NULL);
111 else if(node<OSMSuperSegments->segments[start].node1) /* Check key is not before start */
112 return(NULL);
113 else if(node>OSMSuperSegments->segments[end].node1) /* Check key is not after end */
114 return(NULL);
115 else
116 {
117 do
118 {
119 mid=(start+end)/2; /* Choose mid point */
120
121 if(OSMSuperSegments->segments[mid].node1<node) /* Mid point is too low */
122 start=mid;
123 else if(OSMSuperSegments->segments[mid].node1>node) /* Mid point is too high */
124 end=mid;
125 else /* Mid point is correct */
126 {found=mid; goto found;}
127 }
128 while((end-start)>1);
129
130 if(OSMSuperSegments->segments[start].node1==node) /* Start is correct */
131 {found=start; goto found;}
132
133 if(OSMSuperSegments->segments[end].node1==node) /* End is correct */
134 {found=end; goto found;}
135 }
136
137 return(NULL);
138
139 found:
140
141 while(found>0 && OSMSuperSegments->segments[found-1].node1==node)
142 found--;
143
144 return(&OSMSuperSegments->segments[found]);
145 }
146
147
148 /*++++++++++++++++++++++++++++++++++++++
149 Find the next super-segment with a particular starting node.
150
151 SuperSegment *FindSuperSegment Returns a pointer to the first super-segment with the specified id.
152
153 SuperSegment *supersegment The current super-segment.
154 ++++++++++++++++++++++++++++++++++++++*/
155
156 SuperSegment *FindNextSuperSegment(SuperSegment *supersegment)
157 {
158 SuperSegment *next=supersegment+1;
159
160 if((next-OSMSuperSegments->segments)==OSMSuperSegments->number)
161 return(NULL);
162
163 if(next->node1==supersegment->node1)
164 return(next);
165
166 return(NULL);
167 }
168
169
170 /*++++++++++++++++++++++++++++++++++++++
171 Select the super-segments from the list of segments.
172 ++++++++++++++++++++++++++++++++++++++*/
173
174 void ChooseSuperSegments(void)
175 {
176 assert(!loaded); /* Must not be loaded */
177
178
179 /* Check that the whole thing is allocated. */
180
181 if(!OSMSuperSegments)
182 {
183 alloced=INCREMENT;
184 OSMSuperSegments=(SuperSegments*)malloc(sizeof(SuperSegments)-sizeof(OSMSuperSegments->segments)+alloced*sizeof(SuperSegment));
185
186 OSMSuperSegments->number=0;
187 }
188
189 }
190
191
192 /*++++++++++++++++++++++++++++++++++++++
193 Append a super-segment to a newly created segment list (unsorted).
194
195 node_t node1 The first node in the super-segment.
196
197 node_t node2 The second node in the super-segment.
198 ++++++++++++++++++++++++++++++++++++++*/
199
200 static void append_super_segment(node_t node1,node_t node2)
201 {
202 assert(!loaded); /* Must not be loaded */
203
204 /* Check that the whole thing is allocated. */
205
206 if(!OSMSuperSegments)
207 {
208 alloced=INCREMENT;
209 OSMSuperSegments=(SuperSegments*)malloc(sizeof(SuperSegments)-sizeof(OSMSuperSegments->segments)+alloced*sizeof(SuperSegment));
210
211 OSMSuperSegments->number=0;
212 }
213
214 /* Check that the arrays have enough space. */
215
216 if(OSMSuperSegments->number==alloced)
217 {
218 alloced+=INCREMENT;
219 OSMSuperSegments=(SuperSegments*)realloc((void*)OSMSuperSegments,sizeof(SuperSegments)-sizeof(OSMSuperSegments->segments)+alloced*sizeof(SuperSegment));
220 }
221
222 /* Insert the super-segment */
223
224 OSMSuperSegments->segments[OSMSuperSegments->number].node1=node1;
225 OSMSuperSegments->segments[OSMSuperSegments->number].node2=node2;
226 OSMSuperSegments->segments[OSMSuperSegments->number].distance=0;
227 OSMSuperSegments->segments[OSMSuperSegments->number].duration=0;
228
229 OSMSuperSegments->number++;
230
231 sorted=0;
232 }
233
234
235 /*++++++++++++++++++++++++++++++++++++++
236 Sort the super-segment list.
237 ++++++++++++++++++++++++++++++++++++++*/
238
239 void SortSuperSegmentList(void)
240 {
241 assert(!loaded); /* Must not be loaded */
242
243 qsort(OSMSuperSegments->segments,OSMSuperSegments->number,sizeof(SuperSegment),(int (*)(const void*,const void*))sort_by_id);
244
245 sorted=1;
246 }
247
248
249 /*++++++++++++++++++++++++++++++++++++++
250 Sort the super-segments into id order.
251
252 int sort_by_id Returns the comparison of the node fields.
253
254 SuperSegment *a The first SuperSegment.
255
256 SuperSegment *b The second SuperSegment.
257 ++++++++++++++++++++++++++++++++++++++*/
258
259 static int sort_by_id(SuperSegment *a,SuperSegment *b)
260 {
261 node_t a_id1=a->node1,a_id2=a->node2;
262 node_t b_id1=b->node1,b_id2=b->node2;
263
264 if(a_id1==b_id1)
265 return(a_id2-b_id2);
266 else
267 return(a_id1-b_id1);
268 }
269
270
271 /*++++++++++++++++++++++++++++++++++++++
272 Assign the lengths and durations to all of the super-segments.
273 ++++++++++++++++++++++++++++++++++++++*/
274
275 void FixupSuperSegmentLengths(void)
276 {
277 int i;
278
279 assert(!loaded); /* Must not be loaded */
280
281 assert(sorted); /* Must be sorted */
282
283 for(i=0;i<OSMSuperSegments->number;i++)
284 {
285 // Node *node1=FindNode(OSMSuperSegments->segments[i].node1);
286 // Node *node2=FindNode(OSMSuperSegments->segments[i].node2);
287
288 // distance_t distance=Distance(node1,node2);
289 // duration_t duration=hours_to_duration(distance_to_km(distance)/speed);
290
291 // OSMSuperSegments->segments[i].distance=distance;
292 // OSMSuperSegments->segments[i].duration=duration;
293 }
294 }

Properties

Name Value
cvs:description SuperSegments data type.