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/ways.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations) (download) (as text)
Sat Jan 10 15:59:59 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 9836 byte(s)
Store more information about ways.

1 amb 7 /***************************************
2 amb 30 $Header: /home/amb/CVS/routino/src/ways.c,v 1.5 2009-01-10 15:59:59 amb Exp $
3 amb 7
4     Way 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 <stdlib.h>
17     #include <string.h>
18    
19     #include "functions.h"
20 amb 20 #include "ways.h"
21 amb 7
22    
23 amb 20 /*+ A temporary variable used when sorting +*/
24     static char **sort_names;
25 amb 7
26     /* Functions */
27    
28     static int sort_by_id(Way *a,Way *b);
29     static int sort_by_name(Way *a,Way *b);
30    
31    
32     /*++++++++++++++++++++++++++++++++++++++
33 amb 20 Allocate a new way list.
34 amb 7
35 amb 20 WaysMem *NewWayList Returns the way list.
36 amb 7 ++++++++++++++++++++++++++++++++++++++*/
37    
38 amb 20 WaysMem *NewWayList(void)
39 amb 7 {
40 amb 20 WaysMem *ways;
41 amb 8
42 amb 20 ways=(WaysMem*)malloc(sizeof(WaysMem));
43 amb 7
44 amb 20 ways->alloced=INCREMENT_WAYS;
45     ways->number=0;
46     ways->number_str=0;
47     ways->sorted=0;
48 amb 7
49 amb 20 ways->ways=(Ways*)malloc(sizeof(Ways)+ways->alloced*sizeof(Way));
50     ways->names=(char**)malloc(ways->alloced*sizeof(char*));
51    
52     return(ways);
53 amb 7 }
54    
55    
56     /*++++++++++++++++++++++++++++++++++++++
57 amb 20 Load in a way list from a file.
58    
59     Ways* LoadWayList Returns the way list.
60    
61     const char *filename The name of the file to load.
62     ++++++++++++++++++++++++++++++++++++++*/
63    
64     Ways *LoadWayList(const char *filename)
65     {
66     return((Ways*)MapFile(filename));
67     }
68    
69    
70     /*++++++++++++++++++++++++++++++++++++++
71 amb 7 Save the way list to a file.
72    
73 amb 20 Ways* SaveWayList Returns the way list that has just been saved.
74    
75     WaysMem* ways The set of ways to save.
76    
77 amb 7 const char *filename The name of the file to save.
78     ++++++++++++++++++++++++++++++++++++++*/
79    
80 amb 20 Ways *SaveWayList(WaysMem* ways,const char *filename)
81 amb 7 {
82 amb 20 #ifdef NBINS_WAYS
83     int i,bin=0;
84     #endif
85 amb 7
86 amb 20 assert(ways->sorted); /* Must be sorted */
87 amb 7
88 amb 26 ways->ways->number=ways->number;
89    
90 amb 20 #ifdef NBINS_WAYS
91     for(i=0;i<ways->number;i++)
92     for(;bin<=(ways->ways->ways[i].id%NBINS_WAYS);bin++)
93     ways->ways->offset[bin]=i;
94 amb 7
95 amb 20 for(;bin<=NBINS_WAYS;bin++)
96     ways->ways->offset[bin]=ways->number;
97     #endif
98 amb 7
99 amb 20 if(WriteFile(filename,(void*)ways->ways,sizeof(Ways)-sizeof(ways->ways->ways)+(ways->number+ways->number_str)*sizeof(Way)))
100     assert(0);
101    
102     free(ways->names);
103     free(ways->ways);
104     free(ways);
105    
106     return(LoadWayList(filename));
107 amb 7 }
108    
109    
110     /*++++++++++++++++++++++++++++++++++++++
111     Find a particular way.
112    
113     Way *FindWay Returns a pointer to the way with the specified id.
114    
115 amb 20 Ways* ways The set of ways to process.
116    
117 amb 7 way_t id The way id to look for.
118     ++++++++++++++++++++++++++++++++++++++*/
119    
120 amb 20 Way *FindWay(Ways* ways,way_t id)
121 amb 7 {
122 amb 20 #ifdef NBINS_WAYS
123     int bin=id%NBINS_WAYS;
124     int start=ways->offset[bin];
125     int end=ways->offset[bin+1]-1;
126     #else
127 amb 7 int start=0;
128 amb 20 int end=ways->number-1;
129     #endif
130 amb 7 int mid;
131    
132     /* Binary search - search key exact match only is required.
133     *
134     * # <- start | Check mid and move start or end if it doesn't match
135     * # |
136     * # | Since an exact match is wanted we can set end=mid-1
137     * # <- mid | or start=mid+1 because we know that mid doesn't match.
138     * # |
139     * # | Eventually either end=start or end=start+1 and one of
140     * # <- end | start or end is the wanted one.
141     */
142    
143 amb 20 if(end<start) /* There are no ways */
144 amb 7 return(NULL);
145 amb 20 else if(id<ways->ways[start].id) /* Check key is not before start */
146 amb 7 return(NULL);
147 amb 20 else if(id>ways->ways[end].id) /* Check key is not after end */
148 amb 7 return(NULL);
149     else
150     {
151     do
152     {
153 amb 20 mid=(start+end)/2; /* Choose mid point */
154 amb 7
155 amb 20 if(ways->ways[mid].id<id) /* Mid point is too low */
156 amb 7 start=mid+1;
157 amb 20 else if(ways->ways[mid].id>id) /* Mid point is too high */
158 amb 7 end=mid-1;
159 amb 20 else /* Mid point is correct */
160     return(&ways->ways[mid]);
161 amb 7 }
162     while((end-start)>1);
163    
164 amb 20 if(ways->ways[start].id==id) /* Start is correct */
165     return(&ways->ways[start]);
166 amb 7
167 amb 20 if(ways->ways[end].id==id) /* End is correct */
168     return(&ways->ways[end]);
169 amb 7 }
170    
171     return(NULL);
172     }
173    
174    
175     /*++++++++++++++++++++++++++++++++++++++
176 amb 30 Append a way to a newly created way list (unsorted).
177 amb 7
178 amb 30 Way *AppendWay Returns the newly appended way.
179 amb 7
180 amb 20 WaysMem* ways The set of ways to process.
181    
182 amb 7 way_t id The way identification.
183    
184     const char *name The name or reference of the way.
185 amb 8
186     speed_t speed The speed on the way.
187 amb 7 ++++++++++++++++++++++++++++++++++++++*/
188    
189 amb 30 Way *AppendWay(WaysMem* ways,way_t id,const char *name)
190 amb 7 {
191 amb 20 /* Check that the array has enough space. */
192 amb 7
193 amb 20 if(ways->number==ways->alloced)
194 amb 7 {
195 amb 20 ways->alloced+=INCREMENT_WAYS;
196 amb 7
197 amb 20 ways->ways=(Ways*)realloc((void*)ways->ways,sizeof(Ways)+ways->alloced*sizeof(Way));
198     ways->names=(char**)realloc((void*)ways->names,ways->alloced*sizeof(char*));
199 amb 7 }
200    
201 amb 20 assert(!ways->sorted); /* Must be sorted */
202 amb 7
203     /* Insert the way */
204    
205 amb 20 ways->names[ways->number]=strcpy((char*)malloc(strlen(name)+1),name);
206 amb 7
207 amb 20 ways->ways->ways[ways->number].id=id;
208     ways->ways->ways[ways->number].name=ways->number;
209 amb 7
210 amb 20 ways->number++;
211 amb 7
212 amb 20 ways->sorted=0;
213 amb 30
214     return(&ways->ways->ways[ways->number-1]);
215 amb 7 }
216    
217    
218     /*++++++++++++++++++++++++++++++++++++++
219     Sort the way list.
220 amb 20
221     WaysMem* ways The set of ways to process.
222 amb 7 ++++++++++++++++++++++++++++++++++++++*/
223    
224 amb 20 void SortWayList(WaysMem* ways)
225 amb 7 {
226     char *name=NULL;
227     int i;
228    
229     /* Sort the ways by name */
230    
231 amb 20 sort_names=ways->names;
232     qsort(ways->ways->ways,ways->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_name);
233 amb 7
234 amb 20 /* Setup the offsets for the names in the way array */
235    
236     for(i=0;i<ways->number;i++)
237 amb 7 {
238 amb 20 if(name && !strcmp(name,ways->names[ways->ways->ways[i].name])) /* Same name */
239 amb 7 {
240 amb 20 free(ways->names[ways->ways->ways[i].name]);
241     ways->ways->ways[i].name=ways->ways->ways[i-1].name;
242 amb 7 }
243     else /* Different name */
244     {
245 amb 20 name=ways->names[ways->ways->ways[i].name];
246 amb 7
247 amb 20 if((ways->number+ways->number_str+strlen(name)/sizeof(Way)+1)>=ways->alloced)
248 amb 7 {
249 amb 20 ways->alloced+=INCREMENT_WAYS;
250 amb 7
251 amb 20 ways->ways=(Ways*)realloc((void*)ways->ways,sizeof(Ways)+ways->alloced*sizeof(Way));
252 amb 7 }
253    
254 amb 20 strcpy((char*)&ways->ways->ways[ways->number+ways->number_str],name);
255 amb 7 free(name);
256    
257 amb 20 ways->ways->ways[i].name=ways->number+ways->number_str;
258     name=(char*)&ways->ways->ways[ways->ways->ways[i].name];
259 amb 7
260 amb 20 ways->number_str+=strlen(name)/sizeof(Way)+1;
261 amb 7 }
262     }
263    
264     /* Sort the ways by id */
265    
266 amb 20 qsort(ways->ways->ways,ways->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_id);
267 amb 7
268 amb 20 ways->sorted=1;
269 amb 7 }
270    
271    
272     /*++++++++++++++++++++++++++++++++++++++
273     Sort the ways into id order.
274    
275     int sort_by_id Returns the comparison of the id fields.
276    
277     Way *a The first Way.
278    
279     Way *b The second Way.
280     ++++++++++++++++++++++++++++++++++++++*/
281    
282     static int sort_by_id(Way *a,Way *b)
283     {
284     way_t a_id=a->id;
285     way_t b_id=b->id;
286    
287 amb 20 #ifdef NBINS_WAYS
288     int a_bin=a->id%NBINS_WAYS;
289     int b_bin=b->id%NBINS_WAYS;
290    
291     if(a_bin!=b_bin)
292     return(a_bin-b_bin);
293     #endif
294    
295 amb 7 return(a_id-b_id);
296     }
297    
298    
299     /*++++++++++++++++++++++++++++++++++++++
300     Sort the ways into name order.
301    
302     int sort_by_name Returns the comparison of the name fields.
303    
304     Way *a The first Way.
305    
306     Way *b The second Way.
307     ++++++++++++++++++++++++++++++++++++++*/
308    
309     static int sort_by_name(Way *a,Way *b)
310     {
311 amb 20 char *a_name=sort_names[a->name];
312     char *b_name=sort_names[b->name];
313 amb 7
314     return(strcmp(a_name,b_name));
315     }
316 amb 30
317    
318     /*++++++++++++++++++++++++++++++++++++++
319     Return the name of the way.
320    
321     const char *WayName Returns the name.
322    
323     Ways* ways The set of ways to process.
324    
325     Way *way The way whose name is to be found.
326     ++++++++++++++++++++++++++++++++++++++*/
327    
328     const char *WayName(Ways* ways,Way *way)
329     {
330     return((char*)&ways->ways[way->name]);
331     }
332    
333    
334     /*++++++++++++++++++++++++++++++++++++++
335     Decide on the type of a way given the "highway" parameter.
336    
337     WayType TypeOfWay Returns the type of the way.
338    
339     const char *type The string containing the type of the way.
340     ++++++++++++++++++++++++++++++++++++++*/
341    
342     WayType TypeOfWay(const char *type)
343     {
344     switch(*type)
345     {
346     case 'b':
347     if(!strcmp(type,"byway")) return(Way_Track);
348     if(!strcmp(type,"bridleway")) return(Way_Bridleway);
349     return(Way_Unknown);
350    
351     case 'c':
352     if(!strcmp(type,"cycleway")) return(Way_Cycleway);
353     return(Way_Unknown);
354    
355     case 'f':
356     if(!strcmp(type,"footway")) return(Way_Footway);
357     return(Way_Unknown);
358    
359     case 'm':
360     if(!strncmp(type,"motorway",8)) return(Way_Motorway);
361     if(!strcmp(type,"minor")) return(Way_Unclassfied);
362     return(Way_Unknown);
363    
364     case 'p':
365     if(!strncmp(type,"primary",7)) return(Way_Primary);
366     if(!strcmp(type,"path")) return(Way_Footway);
367     if(!strcmp(type,"pedestrian")) return(Way_Footway);
368     return(Way_Unknown);
369    
370     case 'r':
371     if(!strcmp(type,"road")) return(Way_Unclassfied);
372     if(!strcmp(type,"residential")) return(Way_Residential);
373     return(Way_Unknown);
374    
375     case 's':
376     if(!strncmp(type,"secondary",9)) return(Way_Secondary);
377     if(!strcmp(type,"service")) return(Way_Service);
378     if(!strcmp(type,"steps")) return(Way_Footway);
379     return(Way_Unknown);
380    
381     case 't':
382     if(!strncmp(type,"trunk",5)) return(Way_Trunk);
383     if(!strcmp(type,"tertiary")) return(Way_Tertiary);
384     if(!strcmp(type,"track")) return(Way_Track);
385     return(Way_Unknown);
386    
387     case 'u':
388     if(!strcmp(type,"unclassified")) return(Way_Unclassfied);
389     if(!strcmp(type,"unsurfaced")) return(Way_Track);
390     if(!strcmp(type,"unpaved")) return(Way_Track);
391     return(Way_Unknown);
392    
393     case 'w':
394     if(!strcmp(type,"walkway")) return(Way_Footway);
395     return(Way_Unknown);
396    
397     default:
398     ;
399     }
400    
401     return(Way_Unknown);
402     }

Properties

Name Value
cvs:description Functions for ways.