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 8 - (hide annotations) (download) (as text)
Sun Jan 4 17:51:24 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 7334 byte(s)
Changed the node, way and segment functions and data types.
Removed 'alloced', shortened the prototype array.
Remove the automatic sorting of the data.
Added assert statements.

1 amb 7 /***************************************
2 amb 8 $Header: /home/amb/CVS/routino/src/ways.c,v 1.2 2009-01-04 17:51:24 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     #include "types.h"
21    
22     #define INCREMENT 256*1024
23    
24     /*+ The list of ways +*/
25     Ways *OSMWays=NULL;
26    
27     /*+ Is the data sorted and therefore searchable? +*/
28     static int sorted=0;
29    
30 amb 8 /*+ 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 amb 7 /*+ The list of names for the ways before they are merged into the main data structure. +*/
37     static char **names=NULL;
38    
39     /* Functions */
40    
41     static int sort_by_id(Way *a,Way *b);
42     static int sort_by_name(Way *a,Way *b);
43    
44    
45     /*++++++++++++++++++++++++++++++++++++++
46     Load in a way list from a file.
47    
48     const char *filename The name of the file to load.
49     ++++++++++++++++++++++++++++++++++++++*/
50    
51 amb 8 void LoadWayList(const char *filename)
52 amb 7 {
53 amb 8 assert(!OSMWays);
54    
55 amb 7 OSMWays=(Ways*)MapFile(filename);
56    
57 amb 8 assert(OSMWays);
58 amb 7
59 amb 8 sorted=1;
60     loaded=1;
61 amb 7 }
62    
63    
64     /*++++++++++++++++++++++++++++++++++++++
65     Save the way list to a file.
66    
67     const char *filename The name of the file to save.
68     ++++++++++++++++++++++++++++++++++++++*/
69    
70 amb 8 void SaveWayList(const char *filename)
71 amb 7 {
72     int retval;
73    
74 amb 8 assert(!loaded); /* Must not be loaded */
75 amb 7
76 amb 8 assert(sorted); /* Must be sorted */
77 amb 7
78     retval=WriteFile(filename,OSMWays,sizeof(Ways)-sizeof(OSMWays->ways)+(OSMWays->number+OSMWays->number_str)*sizeof(Way));
79    
80 amb 8 assert(!retval); /* Must be zero */
81 amb 7 }
82    
83    
84     /*++++++++++++++++++++++++++++++++++++++
85     Find a particular way.
86    
87     Way *FindWay Returns a pointer to the way with the specified id.
88    
89     way_t id The way id to look for.
90     ++++++++++++++++++++++++++++++++++++++*/
91    
92     Way *FindWay(way_t id)
93     {
94     int start=0;
95     int end=OSMWays->number-1;
96     int mid;
97    
98 amb 8 assert(sorted); /* Must be sorted */
99 amb 7
100     /* Binary search - search key exact match only is required.
101     *
102     * # <- start | Check mid and move start or end if it doesn't match
103     * # |
104     * # | Since an exact match is wanted we can set end=mid-1
105     * # <- mid | or start=mid+1 because we know that mid doesn't match.
106     * # |
107     * # | Eventually either end=start or end=start+1 and one of
108     * # <- end | start or end is the wanted one.
109     */
110    
111     if(OSMWays->number==0) /* There are no ways */
112     return(NULL);
113     else if(id<OSMWays->ways[start].id) /* Check key is not before start */
114     return(NULL);
115     else if(id>OSMWays->ways[end].id) /* Check key is not after end */
116     return(NULL);
117     else
118     {
119     do
120     {
121     mid=(start+end)/2; /* Choose mid point */
122    
123     if(OSMWays->ways[mid].id<id) /* Mid point is too low */
124     start=mid+1;
125     else if(OSMWays->ways[mid].id>id) /* Mid point is too high */
126     end=mid-1;
127     else /* Mid point is correct */
128     return(&OSMWays->ways[mid]);
129     }
130     while((end-start)>1);
131    
132     if(OSMWays->ways[start].id==id) /* Start is correct */
133     return(&OSMWays->ways[start]);
134    
135     if(OSMWays->ways[end].id==id) /* End is correct */
136     return(&OSMWays->ways[end]);
137     }
138    
139     return(NULL);
140     }
141    
142    
143     /*++++++++++++++++++++++++++++++++++++++
144     Return the name of the way.
145    
146     const char *WayName Returns the name.
147    
148     Way *way The way whose name is to be found.
149     ++++++++++++++++++++++++++++++++++++++*/
150    
151     const char *WayName(Way *way)
152     {
153 amb 8 assert(sorted); /* Must be sorted */
154 amb 7
155     return((char*)&OSMWays->ways[(off_t)way->name]);
156     }
157    
158    
159     /*++++++++++++++++++++++++++++++++++++++
160     Append a way to a newly created way list (unsorted).
161    
162     way_t id The way identification.
163    
164     const char *name The name or reference of the way.
165 amb 8
166     speed_t speed The speed on the way.
167 amb 7 ++++++++++++++++++++++++++++++++++++++*/
168    
169 amb 8 void AppendWay(way_t id,const char *name,speed_t speed)
170 amb 7 {
171 amb 8 assert(!loaded); /* Must not be loaded */
172 amb 7
173 amb 8 assert(!sorted); /* Must not be sorted */
174    
175 amb 7 /* Check that the whole thing is allocated. */
176    
177     if(!OSMWays)
178     {
179 amb 8 alloced=INCREMENT;
180     OSMWays=(Ways*)malloc(sizeof(Ways)-sizeof(OSMWays->ways)+alloced*sizeof(Way));
181 amb 7
182     OSMWays->number=0;
183     OSMWays->number_str=0;
184    
185 amb 8 names=(char**)malloc(alloced*sizeof(char*));
186 amb 7 }
187    
188     /* Check that the arrays have enough space. */
189    
190 amb 8 if(OSMWays->number==alloced)
191 amb 7 {
192 amb 8 alloced+=INCREMENT;
193     OSMWays=(Ways*)realloc((void*)OSMWays,sizeof(Ways)-sizeof(OSMWays->ways)+alloced*sizeof(Way));
194 amb 7
195 amb 8 names=(char**)realloc((void*)names,alloced*sizeof(char*));
196 amb 7 }
197    
198     /* Insert the way */
199    
200     names[OSMWays->number]=strcpy((char*)malloc(strlen(name)+1),name);
201    
202     OSMWays->ways[OSMWays->number].id=id;
203 amb 8 OSMWays->ways[OSMWays->number].name=OSMWays->number;
204     OSMWays->ways[OSMWays->number].speed=speed;
205 amb 7
206     OSMWays->number++;
207    
208     sorted=0;
209     }
210    
211    
212     /*++++++++++++++++++++++++++++++++++++++
213     Sort the way list.
214     ++++++++++++++++++++++++++++++++++++++*/
215    
216 amb 8 void SortWayList(void)
217 amb 7 {
218     char *name=NULL;
219     int i;
220    
221 amb 8 assert(!loaded); /* Must not be loaded */
222    
223 amb 7 /* Sort the ways by name */
224    
225     qsort(OSMWays->ways,OSMWays->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_name);
226    
227     for(i=0;i<OSMWays->number;i++)
228     {
229 amb 8 if(name && !strcmp(name,names[OSMWays->ways[i].name])) /* Same name */
230 amb 7 {
231 amb 8 free(names[OSMWays->ways[i].name]);
232 amb 7 OSMWays->ways[i].name=OSMWays->ways[i-1].name;
233     }
234     else /* Different name */
235     {
236 amb 8 name=names[OSMWays->ways[i].name];
237 amb 7
238 amb 8 if((OSMWays->number+OSMWays->number_str+strlen(name)/sizeof(Way)+1)>=alloced)
239 amb 7 {
240 amb 8 alloced+=INCREMENT;
241 amb 7
242 amb 8 OSMWays=(Ways*)realloc((void*)OSMWays,sizeof(Ways)-sizeof(OSMWays->ways)+alloced*sizeof(Way));
243 amb 7 }
244    
245     strcpy((char*)&OSMWays->ways[OSMWays->number+OSMWays->number_str],name);
246     free(name);
247    
248 amb 8 OSMWays->ways[i].name=OSMWays->number+OSMWays->number_str;
249     name=(char*)&OSMWays->ways[OSMWays->ways[i].name];
250 amb 7
251     OSMWays->number_str+=strlen(name)/sizeof(Way)+1;
252     }
253     }
254    
255     /* Sort the ways by id */
256    
257     qsort(OSMWays->ways,OSMWays->number,sizeof(Way),(int (*)(const void*,const void*))sort_by_id);
258    
259     sorted=1;
260     }
261    
262    
263     /*++++++++++++++++++++++++++++++++++++++
264     Sort the ways into id order.
265    
266     int sort_by_id Returns the comparison of the id fields.
267    
268     Way *a The first Way.
269    
270     Way *b The second Way.
271     ++++++++++++++++++++++++++++++++++++++*/
272    
273     static int sort_by_id(Way *a,Way *b)
274     {
275     way_t a_id=a->id;
276     way_t b_id=b->id;
277    
278     return(a_id-b_id);
279     }
280    
281    
282     /*++++++++++++++++++++++++++++++++++++++
283     Sort the ways into name order.
284    
285     int sort_by_name Returns the comparison of the name fields.
286    
287     Way *a The first Way.
288    
289     Way *b The second Way.
290     ++++++++++++++++++++++++++++++++++++++*/
291    
292     static int sort_by_name(Way *a,Way *b)
293     {
294 amb 8 char *a_name=names[a->name];
295     char *b_name=names[b->name];
296 amb 7
297     return(strcmp(a_name,b_name));
298     }

Properties

Name Value
cvs:description Functions for ways.