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 54 - (hide annotations) (download) (as text)
Sun Jan 18 16:04:09 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 10741 byte(s)
Added Super-Ways and allow user to select method of transport.

1 amb 7 /***************************************
2 amb 54 $Header: /home/amb/CVS/routino/src/ways.c,v 1.8 2009-01-18 16:03:45 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 assert(ways->sorted); /* Must be sorted */
83 amb 7
84 amb 20 if(WriteFile(filename,(void*)ways->ways,sizeof(Ways)-sizeof(ways->ways->ways)+(ways->number+ways->number_str)*sizeof(Way)))
85     assert(0);
86    
87     free(ways->names);
88     free(ways->ways);
89     free(ways);
90    
91     return(LoadWayList(filename));
92 amb 7 }
93    
94    
95     /*++++++++++++++++++++++++++++++++++++++
96     Find a particular way.
97    
98     Way *FindWay Returns a pointer to the way with the specified id.
99    
100 amb 20 Ways* ways The set of ways to process.
101    
102 amb 7 way_t id The way id to look for.
103     ++++++++++++++++++++++++++++++++++++++*/
104    
105 amb 20 Way *FindWay(Ways* ways,way_t id)
106 amb 7 {
107 amb 20 #ifdef NBINS_WAYS
108     int bin=id%NBINS_WAYS;
109     int start=ways->offset[bin];
110     int end=ways->offset[bin+1]-1;
111     #else
112 amb 7 int start=0;
113 amb 20 int end=ways->number-1;
114     #endif
115 amb 7 int mid;
116    
117     /* Binary search - search key exact match only is required.
118     *
119     * # <- start | Check mid and move start or end if it doesn't match
120     * # |
121     * # | Since an exact match is wanted we can set end=mid-1
122     * # <- mid | or start=mid+1 because we know that mid doesn't match.
123     * # |
124     * # | Eventually either end=start or end=start+1 and one of
125     * # <- end | start or end is the wanted one.
126     */
127    
128 amb 20 if(end<start) /* There are no ways */
129 amb 7 return(NULL);
130 amb 20 else if(id<ways->ways[start].id) /* Check key is not before start */
131 amb 7 return(NULL);
132 amb 20 else if(id>ways->ways[end].id) /* Check key is not after end */
133 amb 7 return(NULL);
134     else
135     {
136     do
137     {
138 amb 20 mid=(start+end)/2; /* Choose mid point */
139 amb 7
140 amb 20 if(ways->ways[mid].id<id) /* Mid point is too low */
141 amb 7 start=mid+1;
142 amb 20 else if(ways->ways[mid].id>id) /* Mid point is too high */
143 amb 7 end=mid-1;
144 amb 20 else /* Mid point is correct */
145     return(&ways->ways[mid]);
146 amb 7 }
147     while((end-start)>1);
148    
149 amb 20 if(ways->ways[start].id==id) /* Start is correct */
150     return(&ways->ways[start]);
151 amb 7
152 amb 20 if(ways->ways[end].id==id) /* End is correct */
153     return(&ways->ways[end]);
154 amb 7 }
155    
156     return(NULL);
157     }
158    
159    
160     /*++++++++++++++++++++++++++++++++++++++
161 amb 30 Append a way to a newly created way list (unsorted).
162 amb 7
163 amb 30 Way *AppendWay Returns the newly appended way.
164 amb 7
165 amb 20 WaysMem* ways The set of ways to process.
166    
167 amb 7 way_t id The way identification.
168    
169     const char *name The name or reference of the way.
170 amb 8
171     speed_t speed The speed on the way.
172 amb 7 ++++++++++++++++++++++++++++++++++++++*/
173    
174 amb 30 Way *AppendWay(WaysMem* ways,way_t id,const char *name)
175 amb 7 {
176 amb 20 /* Check that the array has enough space. */
177 amb 7
178 amb 20 if(ways->number==ways->alloced)
179 amb 7 {
180 amb 20 ways->alloced+=INCREMENT_WAYS;
181 amb 7
182 amb 20 ways->ways=(Ways*)realloc((void*)ways->ways,sizeof(Ways)+ways->alloced*sizeof(Way));
183     ways->names=(char**)realloc((void*)ways->names,ways->alloced*sizeof(char*));
184 amb 7 }
185    
186 amb 20 assert(!ways->sorted); /* Must be sorted */
187 amb 7
188     /* Insert the way */
189    
190 amb 20 ways->names[ways->number]=strcpy((char*)malloc(strlen(name)+1),name);
191 amb 7
192 amb 20 ways->ways->ways[ways->number].id=id;
193     ways->ways->ways[ways->number].name=ways->number;
194 amb 7
195 amb 20 ways->number++;
196 amb 7
197 amb 20 ways->sorted=0;
198 amb 30
199     return(&ways->ways->ways[ways->number-1]);
200 amb 7 }
201    
202    
203     /*++++++++++++++++++++++++++++++++++++++
204     Sort the way list.
205 amb 20
206     WaysMem* ways The set of ways to process.
207 amb 7 ++++++++++++++++++++++++++++++++++++++*/
208    
209 amb 20 void SortWayList(WaysMem* ways)
210 amb 7 {
211     char *name=NULL;
212 amb 37 #ifdef NBINS_WAYS
213     int bin=0;
214     #endif
215 amb 7 int i;
216    
217     /* Sort the ways by name */
218    
219 amb 20 sort_names=ways->names;
220 amb 37
221 amb 20 qsort(ways->ways->ways,ways->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_name);
222 amb 7
223 amb 20 /* Setup the offsets for the names in the way array */
224    
225     for(i=0;i<ways->number;i++)
226 amb 7 {
227 amb 20 if(name && !strcmp(name,ways->names[ways->ways->ways[i].name])) /* Same name */
228 amb 7 {
229 amb 20 free(ways->names[ways->ways->ways[i].name]);
230     ways->ways->ways[i].name=ways->ways->ways[i-1].name;
231 amb 7 }
232     else /* Different name */
233     {
234 amb 20 name=ways->names[ways->ways->ways[i].name];
235 amb 7
236 amb 20 if((ways->number+ways->number_str+strlen(name)/sizeof(Way)+1)>=ways->alloced)
237 amb 7 {
238 amb 20 ways->alloced+=INCREMENT_WAYS;
239 amb 7
240 amb 20 ways->ways=(Ways*)realloc((void*)ways->ways,sizeof(Ways)+ways->alloced*sizeof(Way));
241 amb 7 }
242    
243 amb 20 strcpy((char*)&ways->ways->ways[ways->number+ways->number_str],name);
244 amb 7 free(name);
245    
246 amb 20 ways->ways->ways[i].name=ways->number+ways->number_str;
247     name=(char*)&ways->ways->ways[ways->ways->ways[i].name];
248 amb 7
249 amb 20 ways->number_str+=strlen(name)/sizeof(Way)+1;
250 amb 7 }
251     }
252    
253     /* Sort the ways by id */
254    
255 amb 20 qsort(ways->ways->ways,ways->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_id);
256 amb 7
257 amb 37 while(ways->ways->ways[ways->number-1].id==~0)
258     ways->number--;
259    
260 amb 20 ways->sorted=1;
261 amb 37
262     /* Make it searchable */
263    
264     ways->ways->number=ways->number;
265    
266     #ifdef NBINS_WAYS
267     for(i=0;i<ways->number;i++)
268     for(;bin<=(ways->ways->ways[i].id%NBINS_WAYS);bin++)
269     ways->ways->offset[bin]=i;
270    
271     for(;bin<=NBINS_WAYS;bin++)
272     ways->ways->offset[bin]=ways->number;
273     #endif
274 amb 7 }
275    
276    
277     /*++++++++++++++++++++++++++++++++++++++
278     Sort the ways into id order.
279    
280     int sort_by_id Returns the comparison of the id fields.
281    
282     Way *a The first Way.
283    
284     Way *b The second Way.
285     ++++++++++++++++++++++++++++++++++++++*/
286    
287     static int sort_by_id(Way *a,Way *b)
288     {
289     way_t a_id=a->id;
290     way_t b_id=b->id;
291    
292 amb 20 #ifdef NBINS_WAYS
293     int a_bin=a->id%NBINS_WAYS;
294     int b_bin=b->id%NBINS_WAYS;
295    
296     if(a_bin!=b_bin)
297     return(a_bin-b_bin);
298     #endif
299    
300 amb 37 if(a_id<b_id)
301     return(-1);
302     else if(a_id>b_id)
303     return(1);
304     else /* if(a_id==b_id) */
305     return(0);
306 amb 7 }
307    
308    
309     /*++++++++++++++++++++++++++++++++++++++
310     Sort the ways into name order.
311    
312     int sort_by_name Returns the comparison of the name fields.
313    
314     Way *a The first Way.
315    
316     Way *b The second Way.
317     ++++++++++++++++++++++++++++++++++++++*/
318    
319     static int sort_by_name(Way *a,Way *b)
320     {
321 amb 20 char *a_name=sort_names[a->name];
322     char *b_name=sort_names[b->name];
323 amb 7
324     return(strcmp(a_name,b_name));
325     }
326 amb 30
327    
328     /*++++++++++++++++++++++++++++++++++++++
329     Decide on the type of a way given the "highway" parameter.
330    
331     WayType TypeOfWay Returns the type of the way.
332    
333     const char *type The string containing the type of the way.
334     ++++++++++++++++++++++++++++++++++++++*/
335    
336     WayType TypeOfWay(const char *type)
337     {
338     switch(*type)
339     {
340     case 'b':
341     if(!strcmp(type,"byway")) return(Way_Track);
342     if(!strcmp(type,"bridleway")) return(Way_Bridleway);
343     return(Way_Unknown);
344    
345     case 'c':
346     if(!strcmp(type,"cycleway")) return(Way_Cycleway);
347     return(Way_Unknown);
348    
349     case 'f':
350     if(!strcmp(type,"footway")) return(Way_Footway);
351     return(Way_Unknown);
352    
353     case 'm':
354     if(!strncmp(type,"motorway",8)) return(Way_Motorway);
355     if(!strcmp(type,"minor")) return(Way_Unclassfied);
356     return(Way_Unknown);
357    
358     case 'p':
359     if(!strncmp(type,"primary",7)) return(Way_Primary);
360     if(!strcmp(type,"path")) return(Way_Footway);
361     if(!strcmp(type,"pedestrian")) return(Way_Footway);
362     return(Way_Unknown);
363    
364     case 'r':
365     if(!strcmp(type,"road")) return(Way_Unclassfied);
366     if(!strcmp(type,"residential")) return(Way_Residential);
367     return(Way_Unknown);
368    
369     case 's':
370     if(!strncmp(type,"secondary",9)) return(Way_Secondary);
371     if(!strcmp(type,"service")) return(Way_Service);
372     if(!strcmp(type,"steps")) return(Way_Footway);
373     return(Way_Unknown);
374    
375     case 't':
376     if(!strncmp(type,"trunk",5)) return(Way_Trunk);
377     if(!strcmp(type,"tertiary")) return(Way_Tertiary);
378     if(!strcmp(type,"track")) return(Way_Track);
379     return(Way_Unknown);
380    
381     case 'u':
382     if(!strcmp(type,"unclassified")) return(Way_Unclassfied);
383     if(!strcmp(type,"unsurfaced")) return(Way_Track);
384     if(!strcmp(type,"unpaved")) return(Way_Track);
385     return(Way_Unknown);
386    
387     case 'w':
388     if(!strcmp(type,"walkway")) return(Way_Footway);
389     return(Way_Unknown);
390    
391     default:
392     ;
393     }
394    
395     return(Way_Unknown);
396     }
397 amb 54
398    
399     /*++++++++++++++++++++++++++++++++++++++
400     Decide on the allowed type of transport given the name of it.
401    
402     AllowType AllowedType Returns the type of the transport.
403    
404     const char *transport The string containing the method of transport.
405     ++++++++++++++++++++++++++++++++++++++*/
406    
407     AllowType AllowedType(const char *transport)
408     {
409     switch(*transport)
410     {
411     case 'b':
412     if(!strcmp(transport,"bicycle"))
413     return(Allow_Bicycle);
414     break;
415    
416     case 'f':
417     if(!strcmp(transport,"foot"))
418     return(Allow_Foot);
419     break;
420    
421     case 'g':
422     if(!strcmp(transport,"goods"))
423     return(Allow_Goods);
424     break;
425    
426     case 'h':
427     if(!strcmp(transport,"horse"))
428     return(Allow_Horse);
429     if(!strcmp(transport,"hgv"))
430     return(Allow_HGV);
431     break;
432    
433     case 'm':
434     if(!strcmp(transport,"motorbike"))
435     return(Allow_Motorbike);
436     if(!strcmp(transport,"motorcar"))
437     return(Allow_Motorcar);
438     break;
439    
440     case 'p':
441     if(!strcmp(transport,"psv"))
442     return(Allow_PSV);
443     break;
444    
445     default:
446     ;
447     }
448    
449     return(0);
450     }

Properties

Name Value
cvs:description Functions for ways.