Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/ways.c
Parent Directory
|
Revision Log
Revision 100 -
(show 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 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/ways.c,v 1.22 2009-02-04 18:26:29 amb Exp $ |
3 | |
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 "ways.h" |
21 | |
22 | |
23 | /* Constants */ |
24 | |
25 | /*+ The array size increment for ways - expect ~1,000,000 ways. +*/ |
26 | #define INCREMENT_WAYS 256*1024 |
27 | |
28 | |
29 | /* Functions */ |
30 | |
31 | static int sort_by_index(WayX *a,WayX *b); |
32 | static int sort_by_name(WayX *a,WayX *b); |
33 | |
34 | |
35 | /*++++++++++++++++++++++++++++++++++++++ |
36 | 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 | void *data; |
46 | Ways *ways; |
47 | |
48 | ways=(Ways*)malloc(sizeof(Ways)); |
49 | |
50 | data=MapFile(filename); |
51 | |
52 | if(!data) |
53 | return(NULL); |
54 | |
55 | /* 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 | } |
67 | |
68 | |
69 | /*++++++++++++++++++++++++++++++++++++++ |
70 | 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 | Save the way list to a file. |
94 | |
95 | WaysX* waysx The set of ways to save. |
96 | |
97 | const char *filename The name of the file to save. |
98 | ++++++++++++++++++++++++++++++++++++++*/ |
99 | |
100 | void SaveWayList(WaysX* waysx,const char *filename) |
101 | { |
102 | int i; |
103 | int fd; |
104 | Ways *ways=calloc(1,sizeof(Ways)); |
105 | |
106 | assert(waysx->sorted); /* Must be sorted */ |
107 | |
108 | /* Fill in a Ways structure with the offset of the real data in the file after |
109 | the Way structure itself. */ |
110 | |
111 | ways->number=waysx->number; |
112 | ways->data=NULL; |
113 | ways->ways=(void*)sizeof(Ways); |
114 | ways->names=(void*)sizeof(Ways)+ways->number*sizeof(Way); |
115 | |
116 | /* Write out the Ways structure and then the real data. */ |
117 | |
118 | fd=OpenFile(filename); |
119 | |
120 | WriteFile(fd,ways,sizeof(Ways)); |
121 | |
122 | for(i=0;i<waysx->number;i++) |
123 | WriteFile(fd,&waysx->xdata[i].way,sizeof(Way)); |
124 | |
125 | WriteFile(fd,waysx->names,waysx->length); |
126 | |
127 | CloseFile(fd); |
128 | |
129 | /* Free the fake Ways */ |
130 | |
131 | free(ways); |
132 | } |
133 | |
134 | |
135 | /*++++++++++++++++++++++++++++++++++++++ |
136 | Append a way to a way list. |
137 | |
138 | Way *AppendWay Returns the newly appended way. |
139 | |
140 | WaysX* waysx The set of ways to process. |
141 | |
142 | const char *name The name or reference of the way. |
143 | ++++++++++++++++++++++++++++++++++++++*/ |
144 | |
145 | Way *AppendWay(WaysX* waysx,const char *name) |
146 | { |
147 | assert(!waysx->sorted); /* Must not be sorted */ |
148 | |
149 | waysx->sorted=0; |
150 | |
151 | /* Check that the array has enough space. */ |
152 | |
153 | if(waysx->number==waysx->alloced) |
154 | { |
155 | waysx->alloced+=INCREMENT_WAYS; |
156 | |
157 | waysx->xdata=(WayX*)realloc((void*)waysx->xdata,waysx->alloced*sizeof(WayX)); |
158 | } |
159 | |
160 | /* Insert the way */ |
161 | |
162 | waysx->xdata[waysx->number].name=strcpy((char*)malloc(strlen(name)+1),name); |
163 | |
164 | waysx->xdata[waysx->number].index=waysx->number; |
165 | |
166 | waysx->number++; |
167 | |
168 | return(&waysx->xdata[waysx->number-1].way); |
169 | } |
170 | |
171 | |
172 | /*++++++++++++++++++++++++++++++++++++++ |
173 | Sort the list of ways and fix the names. |
174 | |
175 | WaysX* waysx The set of ways to process. |
176 | ++++++++++++++++++++++++++++++++++++++*/ |
177 | |
178 | void SortWayList(WaysX* waysx) |
179 | { |
180 | int i; |
181 | |
182 | assert(!waysx->sorted); /* Must not be sorted */ |
183 | |
184 | waysx->sorted=1; |
185 | |
186 | /* Sort the ways by name */ |
187 | |
188 | qsort(waysx->xdata,waysx->number,sizeof(WayX),(int (*)(const void*,const void*))sort_by_name); |
189 | |
190 | /* Allocate the new data */ |
191 | |
192 | waysx->names=(char*)malloc(waysx->alloced*sizeof(char)); |
193 | |
194 | /* Setup the offsets for the names in the way array */ |
195 | |
196 | for(i=0;i<waysx->number;i++) |
197 | { |
198 | 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 | else /* Different name */ |
201 | { |
202 | if((waysx->length+strlen(waysx->xdata[i].name)+1)>=waysx->alloced) |
203 | { |
204 | waysx->alloced+=INCREMENT_WAYS; |
205 | |
206 | waysx->names=(char*)realloc((void*)waysx->names,waysx->alloced*sizeof(char)); |
207 | } |
208 | |
209 | strcpy(&waysx->names[waysx->length],waysx->xdata[i].name); |
210 | |
211 | waysx->xdata[i].way.name=waysx->length; |
212 | |
213 | waysx->length+=strlen(waysx->xdata[i].name)+1; |
214 | } |
215 | } |
216 | |
217 | /* Sort the ways by id */ |
218 | |
219 | qsort(waysx->xdata,waysx->number,sizeof(WayX),(int (*)(const void*,const void*))sort_by_index); |
220 | } |
221 | |
222 | |
223 | /*++++++++++++++++++++++++++++++++++++++ |
224 | Sort the ways into index order. |
225 | |
226 | int sort_by_index Returns the comparison of the index fields. |
227 | |
228 | WayX *a The first WayX. |
229 | |
230 | WayX *b The second WayX. |
231 | ++++++++++++++++++++++++++++++++++++++*/ |
232 | |
233 | static int sort_by_index(WayX *a,WayX *b) |
234 | { |
235 | index_t a_index=a->index; |
236 | index_t b_index=b->index; |
237 | |
238 | if(a_index<b_index) |
239 | return(-1); |
240 | else |
241 | return(1); |
242 | } |
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 | static int sort_by_name(WayX *a,WayX *b) |
256 | { |
257 | char *a_name=a->name; |
258 | char *b_name=b->name; |
259 | |
260 | return(strcmp(a_name,b_name)); |
261 | } |
262 | |
263 | |
264 | /*++++++++++++++++++++++++++++++++++++++ |
265 | Decide on the type of a way given the "highway" parameter. |
266 | |
267 | Highway HighwayType Returns the highway type of the way. |
268 | |
269 | const char *highway The string containing the type of the way. |
270 | ++++++++++++++++++++++++++++++++++++++*/ |
271 | |
272 | Highway HighwayType(const char *highway) |
273 | { |
274 | switch(*highway) |
275 | { |
276 | case 'b': |
277 | if(!strcmp(highway,"byway")) return(Way_Track); |
278 | if(!strcmp(highway,"bridleway")) return(Way_Bridleway); |
279 | return(Way_Unknown); |
280 | |
281 | case 'c': |
282 | if(!strcmp(highway,"cycleway")) return(Way_Cycleway); |
283 | return(Way_Unknown); |
284 | |
285 | case 'f': |
286 | if(!strcmp(highway,"footway")) return(Way_Footway); |
287 | return(Way_Unknown); |
288 | |
289 | case 'm': |
290 | if(!strncmp(highway,"motorway",8)) return(Way_Motorway); |
291 | if(!strcmp(highway,"minor")) return(Way_Unclassified); |
292 | return(Way_Unknown); |
293 | |
294 | case 'p': |
295 | 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 | return(Way_Unknown); |
299 | |
300 | case 'r': |
301 | if(!strcmp(highway,"road")) return(Way_Unclassified); |
302 | if(!strcmp(highway,"residential")) return(Way_Residential); |
303 | return(Way_Unknown); |
304 | |
305 | case 's': |
306 | 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 | return(Way_Unknown); |
310 | |
311 | case 't': |
312 | 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 | return(Way_Unknown); |
316 | |
317 | case 'u': |
318 | if(!strcmp(highway,"unclassified")) return(Way_Unclassified); |
319 | if(!strcmp(highway,"unsurfaced")) return(Way_Track); |
320 | if(!strcmp(highway,"unpaved")) return(Way_Track); |
321 | return(Way_Unknown); |
322 | |
323 | case 'w': |
324 | if(!strcmp(highway,"walkway")) return(Way_Footway); |
325 | return(Way_Unknown); |
326 | |
327 | default: |
328 | ; |
329 | } |
330 | |
331 | return(Way_Unknown); |
332 | } |
333 | |
334 | |
335 | /*++++++++++++++++++++++++++++++++++++++ |
336 | Decide on the allowed type of transport given the name of it. |
337 | |
338 | Transport TransportType Returns the type of the transport. |
339 | |
340 | const char *transport The string containing the method of transport. |
341 | ++++++++++++++++++++++++++++++++++++++*/ |
342 | |
343 | Transport TransportType(const char *transport) |
344 | { |
345 | switch(*transport) |
346 | { |
347 | case 'b': |
348 | if(!strcmp(transport,"bicycle")) |
349 | return(Transport_Bicycle); |
350 | break; |
351 | |
352 | case 'f': |
353 | if(!strcmp(transport,"foot")) |
354 | return(Transport_Foot); |
355 | break; |
356 | |
357 | case 'g': |
358 | if(!strcmp(transport,"goods")) |
359 | return(Transport_Goods); |
360 | break; |
361 | |
362 | case 'h': |
363 | if(!strcmp(transport,"horse")) |
364 | return(Transport_Horse); |
365 | if(!strcmp(transport,"hgv")) |
366 | return(Transport_HGV); |
367 | break; |
368 | |
369 | case 'm': |
370 | if(!strcmp(transport,"motorbike")) |
371 | return(Transport_Motorbike); |
372 | if(!strcmp(transport,"motorcar")) |
373 | return(Transport_Motorcar); |
374 | break; |
375 | |
376 | case 'p': |
377 | if(!strcmp(transport,"psv")) |
378 | return(Transport_PSV); |
379 | break; |
380 | |
381 | default: |
382 | return(Transport_None); |
383 | } |
384 | |
385 | return(Transport_None); |
386 | } |
387 | |
388 | |
389 | /*++++++++++++++++++++++++++++++++++++++ |
390 | 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 | case Way_Unclassified: |
412 | return("unclassified"); |
413 | 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 | 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 | return " motorway = Motorway\n" |
481 | " trunk = Trunk\n" |
482 | " primary = Primary\n" |
483 | " secondary = Secondary\n" |
484 | " tertiary = Tertiary\n" |
485 | " unclassified = Unclassified\n" |
486 | " residential = Residential\n" |
487 | " service = Service\n" |
488 | " track = Track\n" |
489 | " bridleway = Bridleway\n" |
490 | " cycleway = Cycleway\n" |
491 | " footway = Footway\n"; |
492 | } |
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 | return " foot = Foot\n" |
504 | " bicycle = Bicycle\n" |
505 | " horse = Horse\n" |
506 | " motorbike = Motorbike\n" |
507 | " 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 | } |
Properties
Name | Value |
---|---|
cvs:description | Functions for ways. |