Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/ways.c
Parent Directory
|
Revision Log
Revision 100 -
(hide annotations)
(download)
(as text)
Wed Feb 4 18:26:29 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 11903 byte(s)
Wed Feb 4 18:26:29 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 11903 byte(s)
Make sure that nodes, segments and ways could be loaded.
1 | amb | 7 | /*************************************** |
2 | amb | 100 | $Header: /home/amb/CVS/routino/src/ways.c,v 1.22 2009-02-04 18:26:29 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 | 96 | /* Constants */ |
24 | |||
25 | /*+ The array size increment for ways - expect ~1,000,000 ways. +*/ | ||
26 | #define INCREMENT_WAYS 256*1024 | ||
27 | |||
28 | |||
29 | amb | 7 | /* Functions */ |
30 | |||
31 | amb | 97 | static int sort_by_index(WayX *a,WayX *b); |
32 | static int sort_by_name(WayX *a,WayX *b); | ||
33 | amb | 7 | |
34 | |||
35 | /*++++++++++++++++++++++++++++++++++++++ | ||
36 | amb | 20 | Load in a way list from a file. |
37 | |||
38 | Ways* LoadWayList Returns the way list. | ||
39 | |||
40 | const char *filename The name of the file to load. | ||
41 | ++++++++++++++++++++++++++++++++++++++*/ | ||
42 | |||
43 | Ways *LoadWayList(const char *filename) | ||
44 | { | ||
45 | amb | 87 | void *data; |
46 | Ways *ways; | ||
47 | |||
48 | ways=(Ways*)malloc(sizeof(Ways)); | ||
49 | |||
50 | data=MapFile(filename); | ||
51 | |||
52 | amb | 100 | if(!data) |
53 | return(NULL); | ||
54 | |||
55 | amb | 87 | /* Copy the Ways structure from the loaded data */ |
56 | |||
57 | *ways=*((Ways*)data); | ||
58 | |||
59 | /* Adjust the pointers in the Ways structure. */ | ||
60 | |||
61 | ways->data =data; | ||
62 | ways->ways =(Way *)(data+(off_t)ways->ways); | ||
63 | ways->names=(char*)(data+(off_t)ways->names); | ||
64 | |||
65 | return(ways); | ||
66 | amb | 20 | } |
67 | |||
68 | |||
69 | /*++++++++++++++++++++++++++++++++++++++ | ||
70 | amb | 97 | Allocate a new way list. |
71 | |||
72 | WaysX *NewWayList Returns the way list. | ||
73 | ++++++++++++++++++++++++++++++++++++++*/ | ||
74 | |||
75 | WaysX *NewWayList(void) | ||
76 | { | ||
77 | WaysX *waysx; | ||
78 | |||
79 | waysx=(WaysX*)malloc(sizeof(WaysX)); | ||
80 | |||
81 | waysx->sorted=0; | ||
82 | waysx->alloced=INCREMENT_WAYS; | ||
83 | waysx->number=0; | ||
84 | waysx->length=0; | ||
85 | |||
86 | waysx->xdata=(WayX*)malloc(waysx->alloced*sizeof(WayX)); | ||
87 | |||
88 | return(waysx); | ||
89 | } | ||
90 | |||
91 | |||
92 | /*++++++++++++++++++++++++++++++++++++++ | ||
93 | amb | 7 | Save the way list to a file. |
94 | |||
95 | amb | 97 | WaysX* waysx The set of ways to save. |
96 | amb | 20 | |
97 | amb | 7 | const char *filename The name of the file to save. |
98 | ++++++++++++++++++++++++++++++++++++++*/ | ||
99 | |||
100 | amb | 97 | void SaveWayList(WaysX* waysx,const char *filename) |
101 | amb | 7 | { |
102 | amb | 87 | int i; |
103 | int fd; | ||
104 | Ways *ways=calloc(1,sizeof(Ways)); | ||
105 | amb | 7 | |
106 | amb | 97 | assert(waysx->sorted); /* Must be sorted */ |
107 | amb | 20 | |
108 | amb | 87 | /* Fill in a Ways structure with the offset of the real data in the file after |
109 | the Way structure itself. */ | ||
110 | amb | 20 | |
111 | amb | 97 | ways->number=waysx->number; |
112 | amb | 87 | ways->data=NULL; |
113 | ways->ways=(void*)sizeof(Ways); | ||
114 | ways->names=(void*)sizeof(Ways)+ways->number*sizeof(Way); | ||
115 | amb | 7 | |
116 | amb | 87 | /* Write out the Ways structure and then the real data. */ |
117 | amb | 7 | |
118 | amb | 87 | fd=OpenFile(filename); |
119 | amb | 7 | |
120 | amb | 97 | WriteFile(fd,ways,sizeof(Ways)); |
121 | amb | 7 | |
122 | amb | 97 | for(i=0;i<waysx->number;i++) |
123 | WriteFile(fd,&waysx->xdata[i].way,sizeof(Way)); | ||
124 | amb | 20 | |
125 | amb | 97 | WriteFile(fd,waysx->names,waysx->length); |
126 | amb | 7 | |
127 | amb | 97 | CloseFile(fd); |
128 | amb | 7 | |
129 | amb | 89 | /* Free the fake Ways */ |
130 | amb | 7 | |
131 | amb | 87 | free(ways); |
132 | } | ||
133 | amb | 7 | |
134 | amb | 87 | |
135 | /*++++++++++++++++++++++++++++++++++++++ | ||
136 | amb | 98 | Append a way to a way list. |
137 | amb | 7 | |
138 | amb | 98 | Way *AppendWay Returns the newly appended way. |
139 | amb | 7 | |
140 | amb | 97 | WaysX* waysx The set of ways to process. |
141 | amb | 20 | |
142 | amb | 7 | const char *name The name or reference of the way. |
143 | ++++++++++++++++++++++++++++++++++++++*/ | ||
144 | |||
145 | amb | 98 | Way *AppendWay(WaysX* waysx,const char *name) |
146 | amb | 7 | { |
147 | amb | 97 | assert(!waysx->sorted); /* Must not be sorted */ |
148 | amb | 87 | |
149 | amb | 97 | waysx->sorted=0; |
150 | amb | 87 | |
151 | amb | 20 | /* Check that the array has enough space. */ |
152 | amb | 7 | |
153 | amb | 97 | if(waysx->number==waysx->alloced) |
154 | amb | 7 | { |
155 | amb | 97 | waysx->alloced+=INCREMENT_WAYS; |
156 | amb | 7 | |
157 | amb | 97 | waysx->xdata=(WayX*)realloc((void*)waysx->xdata,waysx->alloced*sizeof(WayX)); |
158 | amb | 7 | } |
159 | |||
160 | /* Insert the way */ | ||
161 | |||
162 | amb | 97 | waysx->xdata[waysx->number].name=strcpy((char*)malloc(strlen(name)+1),name); |
163 | amb | 7 | |
164 | amb | 97 | waysx->xdata[waysx->number].index=waysx->number; |
165 | amb | 7 | |
166 | amb | 97 | waysx->number++; |
167 | amb | 7 | |
168 | amb | 98 | return(&waysx->xdata[waysx->number-1].way); |
169 | amb | 7 | } |
170 | |||
171 | |||
172 | /*++++++++++++++++++++++++++++++++++++++ | ||
173 | amb | 87 | Sort the list of ways and fix the names. |
174 | amb | 20 | |
175 | amb | 97 | WaysX* waysx The set of ways to process. |
176 | amb | 7 | ++++++++++++++++++++++++++++++++++++++*/ |
177 | |||
178 | amb | 97 | void SortWayList(WaysX* waysx) |
179 | amb | 7 | { |
180 | int i; | ||
181 | |||
182 | amb | 97 | assert(!waysx->sorted); /* Must not be sorted */ |
183 | amb | 87 | |
184 | amb | 97 | waysx->sorted=1; |
185 | amb | 87 | |
186 | amb | 7 | /* Sort the ways by name */ |
187 | |||
188 | amb | 97 | qsort(waysx->xdata,waysx->number,sizeof(WayX),(int (*)(const void*,const void*))sort_by_name); |
189 | amb | 37 | |
190 | amb | 87 | /* Allocate the new data */ |
191 | amb | 7 | |
192 | amb | 97 | waysx->names=(char*)malloc(waysx->alloced*sizeof(char)); |
193 | amb | 87 | |
194 | amb | 20 | /* Setup the offsets for the names in the way array */ |
195 | |||
196 | amb | 97 | for(i=0;i<waysx->number;i++) |
197 | amb | 7 | { |
198 | amb | 97 | if(i && !strcmp(waysx->xdata[i].name,waysx->xdata[i-1].name)) /* Same name */ |
199 | waysx->xdata[i].way.name=waysx->xdata[i-1].way.name; | ||
200 | amb | 87 | else /* Different name */ |
201 | amb | 7 | { |
202 | amb | 97 | if((waysx->length+strlen(waysx->xdata[i].name)+1)>=waysx->alloced) |
203 | amb | 7 | { |
204 | amb | 97 | waysx->alloced+=INCREMENT_WAYS; |
205 | amb | 7 | |
206 | amb | 97 | waysx->names=(char*)realloc((void*)waysx->names,waysx->alloced*sizeof(char)); |
207 | amb | 7 | } |
208 | |||
209 | amb | 97 | strcpy(&waysx->names[waysx->length],waysx->xdata[i].name); |
210 | amb | 7 | |
211 | amb | 97 | waysx->xdata[i].way.name=waysx->length; |
212 | amb | 7 | |
213 | amb | 97 | waysx->length+=strlen(waysx->xdata[i].name)+1; |
214 | amb | 7 | } |
215 | } | ||
216 | |||
217 | /* Sort the ways by id */ | ||
218 | |||
219 | amb | 97 | qsort(waysx->xdata,waysx->number,sizeof(WayX),(int (*)(const void*,const void*))sort_by_index); |
220 | amb | 7 | } |
221 | |||
222 | |||
223 | /*++++++++++++++++++++++++++++++++++++++ | ||
224 | amb | 87 | Sort the ways into index order. |
225 | amb | 7 | |
226 | amb | 87 | int sort_by_index Returns the comparison of the index fields. |
227 | amb | 7 | |
228 | amb | 97 | WayX *a The first WayX. |
229 | amb | 7 | |
230 | amb | 97 | WayX *b The second WayX. |
231 | amb | 7 | ++++++++++++++++++++++++++++++++++++++*/ |
232 | |||
233 | amb | 97 | static int sort_by_index(WayX *a,WayX *b) |
234 | amb | 7 | { |
235 | amb | 96 | index_t a_index=a->index; |
236 | index_t b_index=b->index; | ||
237 | amb | 7 | |
238 | amb | 87 | if(a_index<b_index) |
239 | amb | 37 | return(-1); |
240 | amb | 87 | else |
241 | amb | 37 | return(1); |
242 | amb | 7 | } |
243 | |||
244 | |||
245 | /*++++++++++++++++++++++++++++++++++++++ | ||
246 | Sort the ways into name order. | ||
247 | |||
248 | int sort_by_name Returns the comparison of the name fields. | ||
249 | |||
250 | Way *a The first Way. | ||
251 | |||
252 | Way *b The second Way. | ||
253 | ++++++++++++++++++++++++++++++++++++++*/ | ||
254 | |||
255 | amb | 97 | static int sort_by_name(WayX *a,WayX *b) |
256 | amb | 7 | { |
257 | amb | 87 | char *a_name=a->name; |
258 | char *b_name=b->name; | ||
259 | amb | 7 | |
260 | return(strcmp(a_name,b_name)); | ||
261 | } | ||
262 | amb | 30 | |
263 | |||
264 | /*++++++++++++++++++++++++++++++++++++++ | ||
265 | Decide on the type of a way given the "highway" parameter. | ||
266 | |||
267 | amb | 74 | Highway HighwayType Returns the highway type of the way. |
268 | amb | 30 | |
269 | amb | 74 | const char *highway The string containing the type of the way. |
270 | amb | 30 | ++++++++++++++++++++++++++++++++++++++*/ |
271 | |||
272 | amb | 74 | Highway HighwayType(const char *highway) |
273 | amb | 30 | { |
274 | amb | 74 | switch(*highway) |
275 | amb | 30 | { |
276 | case 'b': | ||
277 | amb | 74 | if(!strcmp(highway,"byway")) return(Way_Track); |
278 | if(!strcmp(highway,"bridleway")) return(Way_Bridleway); | ||
279 | amb | 30 | return(Way_Unknown); |
280 | |||
281 | case 'c': | ||
282 | amb | 74 | if(!strcmp(highway,"cycleway")) return(Way_Cycleway); |
283 | amb | 30 | return(Way_Unknown); |
284 | |||
285 | case 'f': | ||
286 | amb | 74 | if(!strcmp(highway,"footway")) return(Way_Footway); |
287 | amb | 30 | return(Way_Unknown); |
288 | |||
289 | case 'm': | ||
290 | amb | 74 | if(!strncmp(highway,"motorway",8)) return(Way_Motorway); |
291 | amb | 85 | if(!strcmp(highway,"minor")) return(Way_Unclassified); |
292 | amb | 30 | return(Way_Unknown); |
293 | |||
294 | case 'p': | ||
295 | amb | 74 | if(!strncmp(highway,"primary",7)) return(Way_Primary); |
296 | if(!strcmp(highway,"path")) return(Way_Footway); | ||
297 | if(!strcmp(highway,"pedestrian")) return(Way_Footway); | ||
298 | amb | 30 | return(Way_Unknown); |
299 | |||
300 | case 'r': | ||
301 | amb | 85 | if(!strcmp(highway,"road")) return(Way_Unclassified); |
302 | amb | 74 | if(!strcmp(highway,"residential")) return(Way_Residential); |
303 | amb | 30 | return(Way_Unknown); |
304 | |||
305 | case 's': | ||
306 | amb | 74 | if(!strncmp(highway,"secondary",9)) return(Way_Secondary); |
307 | if(!strcmp(highway,"service")) return(Way_Service); | ||
308 | if(!strcmp(highway,"steps")) return(Way_Footway); | ||
309 | amb | 30 | return(Way_Unknown); |
310 | |||
311 | case 't': | ||
312 | amb | 74 | if(!strncmp(highway,"trunk",5)) return(Way_Trunk); |
313 | if(!strcmp(highway,"tertiary")) return(Way_Tertiary); | ||
314 | if(!strcmp(highway,"track")) return(Way_Track); | ||
315 | amb | 30 | return(Way_Unknown); |
316 | |||
317 | case 'u': | ||
318 | amb | 85 | if(!strcmp(highway,"unclassified")) return(Way_Unclassified); |
319 | amb | 74 | if(!strcmp(highway,"unsurfaced")) return(Way_Track); |
320 | if(!strcmp(highway,"unpaved")) return(Way_Track); | ||
321 | amb | 30 | return(Way_Unknown); |
322 | |||
323 | case 'w': | ||
324 | amb | 74 | if(!strcmp(highway,"walkway")) return(Way_Footway); |
325 | amb | 30 | return(Way_Unknown); |
326 | |||
327 | default: | ||
328 | ; | ||
329 | } | ||
330 | |||
331 | return(Way_Unknown); | ||
332 | } | ||
333 | amb | 54 | |
334 | |||
335 | /*++++++++++++++++++++++++++++++++++++++ | ||
336 | Decide on the allowed type of transport given the name of it. | ||
337 | |||
338 | amb | 74 | Transport TransportType Returns the type of the transport. |
339 | amb | 54 | |
340 | const char *transport The string containing the method of transport. | ||
341 | ++++++++++++++++++++++++++++++++++++++*/ | ||
342 | |||
343 | amb | 74 | Transport TransportType(const char *transport) |
344 | amb | 54 | { |
345 | switch(*transport) | ||
346 | { | ||
347 | case 'b': | ||
348 | if(!strcmp(transport,"bicycle")) | ||
349 | amb | 74 | return(Transport_Bicycle); |
350 | amb | 54 | break; |
351 | |||
352 | case 'f': | ||
353 | if(!strcmp(transport,"foot")) | ||
354 | amb | 74 | return(Transport_Foot); |
355 | amb | 54 | break; |
356 | |||
357 | case 'g': | ||
358 | if(!strcmp(transport,"goods")) | ||
359 | amb | 74 | return(Transport_Goods); |
360 | amb | 54 | break; |
361 | |||
362 | case 'h': | ||
363 | if(!strcmp(transport,"horse")) | ||
364 | amb | 74 | return(Transport_Horse); |
365 | amb | 54 | if(!strcmp(transport,"hgv")) |
366 | amb | 74 | return(Transport_HGV); |
367 | amb | 54 | break; |
368 | |||
369 | case 'm': | ||
370 | if(!strcmp(transport,"motorbike")) | ||
371 | amb | 74 | return(Transport_Motorbike); |
372 | amb | 54 | if(!strcmp(transport,"motorcar")) |
373 | amb | 74 | return(Transport_Motorcar); |
374 | amb | 54 | break; |
375 | |||
376 | case 'p': | ||
377 | if(!strcmp(transport,"psv")) | ||
378 | amb | 74 | return(Transport_PSV); |
379 | amb | 54 | break; |
380 | |||
381 | default: | ||
382 | amb | 74 | return(Transport_None); |
383 | amb | 54 | } |
384 | |||
385 | amb | 74 | return(Transport_None); |
386 | amb | 54 | } |
387 | amb | 63 | |
388 | |||
389 | /*++++++++++++++++++++++++++++++++++++++ | ||
390 | amb | 82 | A string containing the name of a type of highway. |
391 | |||
392 | const char *HighwayName Returns the name. | ||
393 | |||
394 | Highway highway The highway type. | ||
395 | ++++++++++++++++++++++++++++++++++++++*/ | ||
396 | |||
397 | const char *HighwayName(Highway highway) | ||
398 | { | ||
399 | switch(highway) | ||
400 | { | ||
401 | case Way_Motorway: | ||
402 | return("motorway"); | ||
403 | case Way_Trunk: | ||
404 | return("trunk"); | ||
405 | case Way_Primary: | ||
406 | return("primary"); | ||
407 | case Way_Secondary: | ||
408 | return("secondary"); | ||
409 | case Way_Tertiary: | ||
410 | return("tertiary"); | ||
411 | amb | 85 | case Way_Unclassified: |
412 | return("unclassified"); | ||
413 | amb | 82 | case Way_Residential: |
414 | return("residential"); | ||
415 | case Way_Service: | ||
416 | return("service"); | ||
417 | case Way_Track: | ||
418 | return("track"); | ||
419 | case Way_Bridleway: | ||
420 | return("bridleway"); | ||
421 | case Way_Cycleway: | ||
422 | return("cycleway"); | ||
423 | case Way_Footway: | ||
424 | return("footway"); | ||
425 | |||
426 | case Way_Unknown: | ||
427 | case Way_OneWay: | ||
428 | case Way_Roundabout: | ||
429 | return(NULL); | ||
430 | } | ||
431 | |||
432 | return(NULL); | ||
433 | } | ||
434 | |||
435 | |||
436 | /*++++++++++++++++++++++++++++++++++++++ | ||
437 | A string containing the name of a type of transport. | ||
438 | |||
439 | const char *TransportName Returns the name. | ||
440 | |||
441 | Transport transport The transport type. | ||
442 | ++++++++++++++++++++++++++++++++++++++*/ | ||
443 | |||
444 | const char *TransportName(Transport transport) | ||
445 | { | ||
446 | switch(transport) | ||
447 | { | ||
448 | case Transport_None: | ||
449 | return("NONE"); | ||
450 | |||
451 | case Transport_Foot: | ||
452 | return("foot"); | ||
453 | case Transport_Bicycle: | ||
454 | return("bicycle"); | ||
455 | case Transport_Horse: | ||
456 | return("horse"); | ||
457 | case Transport_Motorbike: | ||
458 | return("motorbike"); | ||
459 | case Transport_Motorcar: | ||
460 | return("motorcar"); | ||
461 | case Transport_Goods: | ||
462 | return("goods"); | ||
463 | case Transport_HGV: | ||
464 | return("hgv"); | ||
465 | case Transport_PSV: | ||
466 | return("psv"); | ||
467 | } | ||
468 | return(NULL); | ||
469 | } | ||
470 | |||
471 | |||
472 | /*++++++++++++++++++++++++++++++++++++++ | ||
473 | amb | 75 | Returns a list of all the highway types. |
474 | |||
475 | const char *HighwayList Return a list of all the highway types. | ||
476 | ++++++++++++++++++++++++++++++++++++++*/ | ||
477 | |||
478 | const char *HighwayList(void) | ||
479 | { | ||
480 | amb | 87 | return " motorway = Motorway\n" |
481 | " trunk = Trunk\n" | ||
482 | " primary = Primary\n" | ||
483 | " secondary = Secondary\n" | ||
484 | " tertiary = Tertiary\n" | ||
485 | amb | 75 | " unclassified = Unclassified\n" |
486 | amb | 87 | " residential = Residential\n" |
487 | " service = Service\n" | ||
488 | " track = Track\n" | ||
489 | " bridleway = Bridleway\n" | ||
490 | " cycleway = Cycleway\n" | ||
491 | " footway = Footway\n"; | ||
492 | amb | 75 | } |
493 | |||
494 | |||
495 | /*++++++++++++++++++++++++++++++++++++++ | ||
496 | Returns a list of all the transport types. | ||
497 | |||
498 | const char *TransportList Return a list of all the transport types. | ||
499 | ++++++++++++++++++++++++++++++++++++++*/ | ||
500 | |||
501 | const char *TransportList(void) | ||
502 | { | ||
503 | amb | 87 | return " foot = Foot\n" |
504 | " bicycle = Bicycle\n" | ||
505 | " horse = Horse\n" | ||
506 | amb | 75 | " motorbike = Motorbike\n" |
507 | amb | 87 | " motorcar = Motorcar\n" |
508 | " goods = Goods (Small lorry, van)\n" | ||
509 | " hgv = HGV (Heavy Goods Vehicle - large lorry)\n" | ||
510 | " psv = PSV (Public Service Vehicle - bus, coach)\n"; | ||
511 | amb | 75 | } |
Properties
Name | Value |
---|---|
cvs:description | Functions for ways. |