Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/supersegments.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (hide 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 amb 16 /***************************************
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.