Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/supersegments.c
Parent Directory
|
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)
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. |