Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/profiles.c
Parent Directory
|
Revision Log
Revision 449 -
(show annotations)
(download)
(as text)
Mon Jul 12 17:59:42 2010 UTC (14 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 31286 byte(s)
Mon Jul 12 17:59:42 2010 UTC (14 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 31286 byte(s)
Create a files.h header and put some of the most heavily used files.c functions into it and make them inline.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/profiles.c,v 1.43 2010-07-12 17:59:41 amb Exp $ |
3 | |
4 | Load the profiles from a file and the functions for handling them. |
5 | |
6 | Part of the Routino routing software. |
7 | ******************/ /****************** |
8 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | |
10 | This program is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU Affero General Public License as published by |
12 | the Free Software Foundation, either version 3 of the License, or |
13 | (at your option) any later version. |
14 | |
15 | This program is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public License |
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
22 | ***************************************/ |
23 | |
24 | |
25 | #include <stdio.h> |
26 | #include <string.h> |
27 | #include <stdlib.h> |
28 | |
29 | #include "types.h" |
30 | #include "ways.h" |
31 | |
32 | #include "files.h" |
33 | #include "profiles.h" |
34 | #include "functions.h" |
35 | #include "xmlparse.h" |
36 | |
37 | |
38 | /*+ The profiles that have been loaded from file. +*/ |
39 | static Profile **loaded_profiles=NULL; |
40 | |
41 | /*+ The number of profiles that have been loaded from file. +*/ |
42 | static int nloaded_profiles=0; |
43 | |
44 | |
45 | /* The XML tag processing function prototypes */ |
46 | |
47 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); |
48 | //static int RoutinoProfilesType_function(const char *_tag_,int _type_); |
49 | static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport); |
50 | //static int restrictionsType_function(const char *_tag_,int _type_); |
51 | static int lengthType_function(const char *_tag_,int _type_,const char *limit); |
52 | static int widthType_function(const char *_tag_,int _type_,const char *limit); |
53 | static int heightType_function(const char *_tag_,int _type_,const char *limit); |
54 | static int weightType_function(const char *_tag_,int _type_,const char *limit); |
55 | //static int propertiesType_function(const char *_tag_,int _type_); |
56 | static int onewayType_function(const char *_tag_,int _type_,const char *obey); |
57 | static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent); |
58 | //static int preferencesType_function(const char *_tag_,int _type_); |
59 | static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent); |
60 | //static int speedsType_function(const char *_tag_,int _type_); |
61 | static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph); |
62 | |
63 | |
64 | /* The XML tag definitions */ |
65 | |
66 | /*+ The speedType type tag. +*/ |
67 | static xmltag speedType_tag= |
68 | {"speed", |
69 | 2, {"highway","kph"}, |
70 | speedType_function, |
71 | {NULL}}; |
72 | |
73 | /*+ The speedsType type tag. +*/ |
74 | static xmltag speedsType_tag= |
75 | {"speeds", |
76 | 0, {NULL}, |
77 | NULL, |
78 | {&speedType_tag,NULL}}; |
79 | |
80 | /*+ The preferenceType type tag. +*/ |
81 | static xmltag preferenceType_tag= |
82 | {"preference", |
83 | 2, {"highway","percent"}, |
84 | preferenceType_function, |
85 | {NULL}}; |
86 | |
87 | /*+ The preferencesType type tag. +*/ |
88 | static xmltag preferencesType_tag= |
89 | {"preferences", |
90 | 0, {NULL}, |
91 | NULL, |
92 | {&preferenceType_tag,NULL}}; |
93 | |
94 | /*+ The propertyType type tag. +*/ |
95 | static xmltag propertyType_tag= |
96 | {"property", |
97 | 2, {"type","percent"}, |
98 | propertyType_function, |
99 | {NULL}}; |
100 | |
101 | /*+ The onewayType type tag. +*/ |
102 | static xmltag onewayType_tag= |
103 | {"oneway", |
104 | 1, {"obey"}, |
105 | onewayType_function, |
106 | {NULL}}; |
107 | |
108 | /*+ The propertiesType type tag. +*/ |
109 | static xmltag propertiesType_tag= |
110 | {"properties", |
111 | 0, {NULL}, |
112 | NULL, |
113 | {&propertyType_tag,NULL}}; |
114 | |
115 | /*+ The weightType type tag. +*/ |
116 | static xmltag weightType_tag= |
117 | {"weight", |
118 | 1, {"limit"}, |
119 | weightType_function, |
120 | {NULL}}; |
121 | |
122 | /*+ The heightType type tag. +*/ |
123 | static xmltag heightType_tag= |
124 | {"height", |
125 | 1, {"limit"}, |
126 | heightType_function, |
127 | {NULL}}; |
128 | |
129 | /*+ The widthType type tag. +*/ |
130 | static xmltag widthType_tag= |
131 | {"width", |
132 | 1, {"limit"}, |
133 | widthType_function, |
134 | {NULL}}; |
135 | |
136 | /*+ The lengthType type tag. +*/ |
137 | static xmltag lengthType_tag= |
138 | {"length", |
139 | 1, {"limit"}, |
140 | lengthType_function, |
141 | {NULL}}; |
142 | |
143 | /*+ The restrictionsType type tag. +*/ |
144 | static xmltag restrictionsType_tag= |
145 | {"restrictions", |
146 | 0, {NULL}, |
147 | NULL, |
148 | {&onewayType_tag,&weightType_tag,&heightType_tag,&widthType_tag,&lengthType_tag,NULL}}; |
149 | |
150 | /*+ The profileType type tag. +*/ |
151 | static xmltag profileType_tag= |
152 | {"profile", |
153 | 2, {"name","transport"}, |
154 | profileType_function, |
155 | {&speedsType_tag,&preferencesType_tag,&propertiesType_tag,&restrictionsType_tag,NULL}}; |
156 | |
157 | /*+ The RoutinoProfilesType type tag. +*/ |
158 | static xmltag RoutinoProfilesType_tag= |
159 | {"routino-profiles", |
160 | 0, {NULL}, |
161 | NULL, |
162 | {&profileType_tag,NULL}}; |
163 | |
164 | /*+ The xmlDeclaration type tag. +*/ |
165 | static xmltag xmlDeclaration_tag= |
166 | {"xml", |
167 | 2, {"version","encoding"}, |
168 | NULL, |
169 | {NULL}}; |
170 | |
171 | |
172 | /*+ The complete set of tags at the top level. +*/ |
173 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL}; |
174 | |
175 | |
176 | /* The XML tag processing functions */ |
177 | |
178 | |
179 | /*++++++++++++++++++++++++++++++++++++++ |
180 | The function that is called when the speedType XSD type is seen |
181 | |
182 | int speedType_function Returns 0 if no error occured or something else otherwise. |
183 | |
184 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
185 | |
186 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
187 | |
188 | const char *highway The contents of the 'highway' attribute (or NULL if not defined). |
189 | |
190 | const char *kph The contents of the 'kph' attribute (or NULL if not defined). |
191 | ++++++++++++++++++++++++++++++++++++++*/ |
192 | |
193 | static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph) |
194 | { |
195 | if(_type_&XMLPARSE_TAG_START) |
196 | { |
197 | double speed; |
198 | Highway highwaytype; |
199 | |
200 | XMLPARSE_ASSERT_STRING(_tag_,highway); |
201 | |
202 | highwaytype=HighwayType(highway); |
203 | |
204 | if(highwaytype==Way_Count) |
205 | XMLPARSE_INVALID(_tag_,highway); |
206 | |
207 | XMLPARSE_ASSERT_FLOATING(_tag_,kph,speed); |
208 | |
209 | loaded_profiles[nloaded_profiles-1]->speed[highwaytype]=kph_to_speed(speed); |
210 | } |
211 | |
212 | return(0); |
213 | } |
214 | |
215 | |
216 | /*++++++++++++++++++++++++++++++++++++++ |
217 | The function that is called when the speedsType XSD type is seen |
218 | |
219 | int speedsType_function Returns 0 if no error occured or something else otherwise. |
220 | |
221 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
222 | |
223 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
224 | ++++++++++++++++++++++++++++++++++++++*/ |
225 | |
226 | //static int speedsType_function(const char *_tag_,int _type_) |
227 | //{ |
228 | // return(0); |
229 | //} |
230 | |
231 | |
232 | /*++++++++++++++++++++++++++++++++++++++ |
233 | The function that is called when the preferenceType XSD type is seen |
234 | |
235 | int preferenceType_function Returns 0 if no error occured or something else otherwise. |
236 | |
237 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
238 | |
239 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
240 | |
241 | const char *highway The contents of the 'highway' attribute (or NULL if not defined). |
242 | |
243 | const char *percent The contents of the 'percent' attribute (or NULL if not defined). |
244 | ++++++++++++++++++++++++++++++++++++++*/ |
245 | |
246 | static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent) |
247 | { |
248 | if(_type_&XMLPARSE_TAG_START) |
249 | { |
250 | Highway highwaytype; |
251 | double p; |
252 | |
253 | XMLPARSE_ASSERT_STRING(_tag_,highway); |
254 | |
255 | highwaytype=HighwayType(highway); |
256 | |
257 | if(highwaytype==Way_Count) |
258 | XMLPARSE_INVALID(_tag_,highway); |
259 | |
260 | XMLPARSE_ASSERT_FLOATING(_tag_,percent,p); |
261 | |
262 | loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=p; |
263 | } |
264 | |
265 | return(0); |
266 | } |
267 | |
268 | |
269 | /*++++++++++++++++++++++++++++++++++++++ |
270 | The function that is called when the preferencesType XSD type is seen |
271 | |
272 | int preferencesType_function Returns 0 if no error occured or something else otherwise. |
273 | |
274 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
275 | |
276 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
277 | ++++++++++++++++++++++++++++++++++++++*/ |
278 | |
279 | //static int preferencesType_function(const char *_tag_,int _type_) |
280 | //{ |
281 | // return(0); |
282 | //} |
283 | |
284 | |
285 | /*++++++++++++++++++++++++++++++++++++++ |
286 | The function that is called when the propertyType XSD type is seen |
287 | |
288 | int propertyType_function Returns 0 if no error occured or something else otherwise. |
289 | |
290 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
291 | |
292 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
293 | |
294 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
295 | |
296 | const char *percent The contents of the 'percent' attribute (or NULL if not defined). |
297 | ++++++++++++++++++++++++++++++++++++++*/ |
298 | |
299 | static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent) |
300 | { |
301 | if(_type_&XMLPARSE_TAG_START) |
302 | { |
303 | Property property; |
304 | double p; |
305 | |
306 | XMLPARSE_ASSERT_STRING(_tag_,type); |
307 | |
308 | property=PropertyType(type); |
309 | |
310 | if(property==Property_Count) |
311 | XMLPARSE_INVALID(_tag_,type); |
312 | |
313 | XMLPARSE_ASSERT_FLOATING(_tag_,percent,p); |
314 | |
315 | loaded_profiles[nloaded_profiles-1]->props_yes[property]=p; |
316 | } |
317 | |
318 | return(0); |
319 | } |
320 | |
321 | |
322 | /*++++++++++++++++++++++++++++++++++++++ |
323 | The function that is called when the onewayType XSD type is seen |
324 | |
325 | int onewayType_function Returns 0 if no error occured or something else otherwise. |
326 | |
327 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
328 | |
329 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
330 | |
331 | const char *obey The contents of the 'obey' attribute (or NULL if not defined). |
332 | ++++++++++++++++++++++++++++++++++++++*/ |
333 | |
334 | static int onewayType_function(const char *_tag_,int _type_,const char *obey) |
335 | { |
336 | if(_type_&XMLPARSE_TAG_START) |
337 | { |
338 | int o; |
339 | |
340 | XMLPARSE_ASSERT_INTEGER(_tag_,obey,o); |
341 | |
342 | loaded_profiles[nloaded_profiles-1]->oneway=!!o; |
343 | } |
344 | |
345 | return(0); |
346 | } |
347 | |
348 | |
349 | /*++++++++++++++++++++++++++++++++++++++ |
350 | The function that is called when the propertiesType XSD type is seen |
351 | |
352 | int propertiesType_function Returns 0 if no error occured or something else otherwise. |
353 | |
354 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
355 | |
356 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
357 | ++++++++++++++++++++++++++++++++++++++*/ |
358 | |
359 | //static int propertiesType_function(const char *_tag_,int _type_) |
360 | //{ |
361 | // return(0); |
362 | //} |
363 | |
364 | |
365 | /*++++++++++++++++++++++++++++++++++++++ |
366 | The function that is called when the weightType XSD type is seen |
367 | |
368 | int weightType_function Returns 0 if no error occured or something else otherwise. |
369 | |
370 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
371 | |
372 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
373 | |
374 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
375 | ++++++++++++++++++++++++++++++++++++++*/ |
376 | |
377 | static int weightType_function(const char *_tag_,int _type_,const char *limit) |
378 | { |
379 | if(_type_&XMLPARSE_TAG_START) |
380 | { |
381 | double l; |
382 | |
383 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
384 | |
385 | loaded_profiles[nloaded_profiles-1]->weight=tonnes_to_weight(l); |
386 | } |
387 | |
388 | return(0); |
389 | } |
390 | |
391 | |
392 | /*++++++++++++++++++++++++++++++++++++++ |
393 | The function that is called when the heightType XSD type is seen |
394 | |
395 | int heightType_function Returns 0 if no error occured or something else otherwise. |
396 | |
397 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
398 | |
399 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
400 | |
401 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
402 | ++++++++++++++++++++++++++++++++++++++*/ |
403 | |
404 | static int heightType_function(const char *_tag_,int _type_,const char *limit) |
405 | { |
406 | if(_type_&XMLPARSE_TAG_START) |
407 | { |
408 | double l; |
409 | |
410 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
411 | |
412 | loaded_profiles[nloaded_profiles-1]->height=metres_to_height(l); |
413 | } |
414 | |
415 | return(0); |
416 | } |
417 | |
418 | |
419 | /*++++++++++++++++++++++++++++++++++++++ |
420 | The function that is called when the widthType XSD type is seen |
421 | |
422 | int widthType_function Returns 0 if no error occured or something else otherwise. |
423 | |
424 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
425 | |
426 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
427 | |
428 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
429 | ++++++++++++++++++++++++++++++++++++++*/ |
430 | |
431 | static int widthType_function(const char *_tag_,int _type_,const char *limit) |
432 | { |
433 | if(_type_&XMLPARSE_TAG_START) |
434 | { |
435 | double l; |
436 | |
437 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
438 | |
439 | loaded_profiles[nloaded_profiles-1]->width=metres_to_width(l); |
440 | } |
441 | |
442 | return(0); |
443 | } |
444 | |
445 | |
446 | /*++++++++++++++++++++++++++++++++++++++ |
447 | The function that is called when the lengthType XSD type is seen |
448 | |
449 | int lengthType_function Returns 0 if no error occured or something else otherwise. |
450 | |
451 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
452 | |
453 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
454 | |
455 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
456 | ++++++++++++++++++++++++++++++++++++++*/ |
457 | |
458 | static int lengthType_function(const char *_tag_,int _type_,const char *limit) |
459 | { |
460 | if(_type_&XMLPARSE_TAG_START) |
461 | { |
462 | double l; |
463 | |
464 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
465 | |
466 | loaded_profiles[nloaded_profiles-1]->length=metres_to_length(l); |
467 | } |
468 | |
469 | return(0); |
470 | } |
471 | |
472 | |
473 | /*++++++++++++++++++++++++++++++++++++++ |
474 | The function that is called when the restrictionsType XSD type is seen |
475 | |
476 | int restrictionsType_function Returns 0 if no error occured or something else otherwise. |
477 | |
478 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
479 | |
480 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
481 | ++++++++++++++++++++++++++++++++++++++*/ |
482 | |
483 | //static int restrictionsType_function(const char *_tag_,int _type_) |
484 | //{ |
485 | // return(0); |
486 | //} |
487 | |
488 | |
489 | /*++++++++++++++++++++++++++++++++++++++ |
490 | The function that is called when the profileType XSD type is seen |
491 | |
492 | int profileType_function Returns 0 if no error occured or something else otherwise. |
493 | |
494 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
495 | |
496 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
497 | |
498 | const char *name The contents of the 'name' attribute (or NULL if not defined). |
499 | |
500 | const char *transport The contents of the 'transport' attribute (or NULL if not defined). |
501 | ++++++++++++++++++++++++++++++++++++++*/ |
502 | |
503 | static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport) |
504 | { |
505 | if(_type_&XMLPARSE_TAG_START) |
506 | { |
507 | Transport transporttype; |
508 | int i; |
509 | |
510 | XMLPARSE_ASSERT_STRING(_tag_,name); |
511 | XMLPARSE_ASSERT_STRING(_tag_,transport); |
512 | |
513 | for(i=0;i<nloaded_profiles;i++) |
514 | if(!strcmp(name,loaded_profiles[i]->name)) |
515 | XMLPARSE_MESSAGE(_tag_,"profile name must be unique"); |
516 | |
517 | transporttype=TransportType(transport); |
518 | |
519 | if(transporttype==Transport_None) |
520 | XMLPARSE_INVALID(_tag_,transport); |
521 | |
522 | if((nloaded_profiles%16)==0) |
523 | loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*)); |
524 | |
525 | nloaded_profiles++; |
526 | |
527 | loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile)); |
528 | |
529 | loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name); |
530 | loaded_profiles[nloaded_profiles-1]->transport=transporttype; |
531 | } |
532 | |
533 | return(0); |
534 | } |
535 | |
536 | |
537 | /*++++++++++++++++++++++++++++++++++++++ |
538 | The function that is called when the RoutinoProfilesType XSD type is seen |
539 | |
540 | int RoutinoProfilesType_function Returns 0 if no error occured or something else otherwise. |
541 | |
542 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
543 | |
544 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
545 | ++++++++++++++++++++++++++++++++++++++*/ |
546 | |
547 | //static int RoutinoProfilesType_function(const char *_tag_,int _type_) |
548 | //{ |
549 | // return(0); |
550 | //} |
551 | |
552 | |
553 | /*++++++++++++++++++++++++++++++++++++++ |
554 | The function that is called when the XML declaration is seen |
555 | |
556 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. |
557 | |
558 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
559 | |
560 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
561 | |
562 | const char *version The contents of the 'version' attribute (or NULL if not defined). |
563 | |
564 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). |
565 | ++++++++++++++++++++++++++++++++++++++*/ |
566 | |
567 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) |
568 | //{ |
569 | // return(0); |
570 | //} |
571 | |
572 | |
573 | /*++++++++++++++++++++++++++++++++++++++ |
574 | The XML profile parser. |
575 | |
576 | int ParseXMLProfiles Returns 0 if OK or something else in case of an error. |
577 | |
578 | const char *filename The name of the file to read. |
579 | ++++++++++++++++++++++++++++++++++++++*/ |
580 | |
581 | int ParseXMLProfiles(const char *filename) |
582 | { |
583 | int retval; |
584 | |
585 | if(!ExistsFile(filename)) |
586 | { |
587 | fprintf(stderr,"Error: Specified profiles file '%s' does not exist.\n",filename); |
588 | return(1); |
589 | } |
590 | |
591 | FILE *file=fopen(filename,"r"); |
592 | |
593 | if(!file) |
594 | { |
595 | fprintf(stderr,"Error: Cannot open profiles file '%s' for reading.\n",filename); |
596 | return(1); |
597 | } |
598 | |
599 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME); |
600 | |
601 | fclose(file); |
602 | |
603 | if(retval) |
604 | { |
605 | int i; |
606 | |
607 | for(i=0;i<nloaded_profiles;i++) |
608 | free(loaded_profiles[i]); |
609 | free(loaded_profiles); |
610 | |
611 | nloaded_profiles=0; |
612 | |
613 | return(1); |
614 | } |
615 | |
616 | return(0); |
617 | } |
618 | |
619 | |
620 | /*++++++++++++++++++++++++++++++++++++++ |
621 | Get the profile for a type of transport. |
622 | |
623 | Profile *GetProfile Returns a pointer to the profile. |
624 | |
625 | const char *name The name of the profile. |
626 | ++++++++++++++++++++++++++++++++++++++*/ |
627 | |
628 | Profile *GetProfile(const char *name) |
629 | { |
630 | int i; |
631 | |
632 | for(i=0;i<nloaded_profiles;i++) |
633 | if(!strcmp(loaded_profiles[i]->name,name)) |
634 | return(loaded_profiles[i]); |
635 | |
636 | return(NULL); |
637 | } |
638 | |
639 | |
640 | /*++++++++++++++++++++++++++++++++++++++ |
641 | Update a profile with highway preference scaling factor. |
642 | |
643 | int UpdateProfile Returns 1 in case of a problem. |
644 | |
645 | Profile *profile The profile to be updated. |
646 | |
647 | Ways *ways The set of ways to use. |
648 | ++++++++++++++++++++++++++++++++++++++*/ |
649 | |
650 | int UpdateProfile(Profile *profile,Ways *ways) |
651 | { |
652 | score_t hmax=0; |
653 | int i; |
654 | |
655 | /* Fix up the allowed transport types. */ |
656 | |
657 | profile->allow=ALLOWED(profile->transport); |
658 | |
659 | if(!(profile->allow & ways->allow)) |
660 | return(1); |
661 | |
662 | /* Normalise the highway preferences into the range 0 -> 1 */ |
663 | |
664 | for(i=1;i<Way_Count;i++) |
665 | { |
666 | if(profile->highway[i]<0) |
667 | profile->highway[i]=0; |
668 | |
669 | if(profile->highway[i]>hmax) |
670 | hmax=profile->highway[i]; |
671 | } |
672 | |
673 | if(hmax==0) |
674 | return(1); |
675 | |
676 | for(i=1;i<Way_Count;i++) |
677 | profile->highway[i]/=hmax; |
678 | |
679 | /* Normalise the property preferences into the range 0 -> 2 */ |
680 | |
681 | for(i=1;i<Property_Count;i++) |
682 | { |
683 | if(profile->props_yes[i]<0) |
684 | profile->props_yes[i]=0; |
685 | |
686 | if(profile->props_yes[i]>100) |
687 | profile->props_yes[i]=100; |
688 | |
689 | profile->props_yes[i]/=50; |
690 | profile->props_no [i] =2-profile->props_yes[i]; |
691 | } |
692 | |
693 | /* Find the fastest preferred speed */ |
694 | |
695 | profile->max_speed=0; |
696 | |
697 | for(i=1;i<Way_Count;i++) |
698 | if(profile->speed[i]>profile->max_speed) |
699 | profile->max_speed=profile->speed[i]; |
700 | |
701 | if(profile->max_speed==0) |
702 | return(1); |
703 | |
704 | /* Find the most preferred property combination */ |
705 | |
706 | profile->max_pref=1; /* since highway prefs were normalised to 1 */ |
707 | |
708 | for(i=1;i<Property_Count;i++) |
709 | if(ways->props & PROPERTIES(i)) |
710 | { |
711 | if(profile->props_yes[i]>profile->props_no[i]) |
712 | profile->max_pref*=profile->props_yes[i]; |
713 | else |
714 | profile->max_pref*=profile->props_no[i]; |
715 | } |
716 | |
717 | return(0); |
718 | } |
719 | |
720 | |
721 | /*++++++++++++++++++++++++++++++++++++++ |
722 | Print out a profile. |
723 | |
724 | const Profile *profile The profile to print. |
725 | ++++++++++++++++++++++++++++++++++++++*/ |
726 | |
727 | void PrintProfile(const Profile *profile) |
728 | { |
729 | unsigned int i; |
730 | |
731 | printf("Profile\n=======\n"); |
732 | |
733 | printf("\n"); |
734 | |
735 | printf("Transport: %s\n",TransportName(profile->transport)); |
736 | |
737 | printf("\n"); |
738 | |
739 | for(i=1;i<Way_Count;i++) |
740 | printf("Highway %-12s: %3d%%\n",HighwayName(i),(int)profile->highway[i]); |
741 | |
742 | printf("\n"); |
743 | |
744 | for(i=1;i<Way_Count;i++) |
745 | if(profile->highway[i]) |
746 | printf("Speed on %-12s: %3d km/h / %2.0f mph\n",HighwayName(i),profile->speed[i],(double)profile->speed[i]/1.6); |
747 | |
748 | printf("\n"); |
749 | |
750 | for(i=1;i<Property_Count;i++) |
751 | printf("Highway property %-12s: %3d%%\n",PropertyName(i),(int)profile->props_yes[i]); |
752 | |
753 | printf("\n"); |
754 | |
755 | printf("Obey one-way : %s\n",profile->oneway?"yes":"no"); |
756 | printf("Minimum weight: %.1f tonnes\n",weight_to_tonnes(profile->weight)); |
757 | printf("Minimum height: %.1f metres\n",height_to_metres(profile->height)); |
758 | printf("Minimum width : %.1f metres\n",width_to_metres(profile->width)); |
759 | printf("Minimum length: %.1f metres\n",length_to_metres(profile->length)); |
760 | } |
761 | |
762 | |
763 | /*++++++++++++++++++++++++++++++++++++++ |
764 | Print out the profiles as XML for use as program input. |
765 | ++++++++++++++++++++++++++++++++++++++*/ |
766 | |
767 | void PrintProfilesXML(void) |
768 | { |
769 | unsigned int i,j; |
770 | char *padding=" "; |
771 | |
772 | printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); |
773 | printf("\n"); |
774 | |
775 | printf("<routino-profiles xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"routino-profiles.xsd\">\n"); |
776 | printf("\n"); |
777 | |
778 | for(j=0;j<nloaded_profiles;j++) |
779 | { |
780 | printf(" <profile name=\"%s\" transport=\"%s\">\n",loaded_profiles[j]->name,TransportName(loaded_profiles[j]->transport)); |
781 | |
782 | printf(" <speeds>\n"); |
783 | for(i=1;i<Way_Count;i++) |
784 | printf(" <speed highway=\"%s\"%s kph=\"%d\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->speed[i]); |
785 | printf(" </speeds>\n"); |
786 | |
787 | printf(" <preferences>\n"); |
788 | for(i=1;i<Way_Count;i++) |
789 | printf(" <preference highway=\"%s\"%s percent=\"%.0f\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->highway[i]); |
790 | printf(" </preferences>\n"); |
791 | |
792 | printf(" <properties>\n"); |
793 | for(i=1;i<Property_Count;i++) |
794 | printf(" <property type=\"%s\"%s percent=\"%.0f\" />\n",PropertyName(i),padding+6+strlen(PropertyName(i)),loaded_profiles[j]->props_yes[i]); |
795 | printf(" </properties>\n"); |
796 | |
797 | printf(" <restrictions>\n"); |
798 | printf(" <oneway obey=\"%d\" /> \n",loaded_profiles[j]->oneway); |
799 | printf(" <weight limit=\"%.1f\" />\n",weight_to_tonnes(loaded_profiles[j]->weight)); |
800 | printf(" <height limit=\"%.1f\" />\n",height_to_metres(loaded_profiles[j]->height)); |
801 | printf(" <width limit=\"%.1f\" />\n",width_to_metres(loaded_profiles[j]->width)); |
802 | printf(" <length limit=\"%.1f\" />\n",length_to_metres(loaded_profiles[j]->length)); |
803 | printf(" </restrictions>\n"); |
804 | |
805 | printf(" </profile>\n"); |
806 | printf("\n"); |
807 | } |
808 | |
809 | printf("</routino-profiles>\n"); |
810 | } |
811 | |
812 | |
813 | /*++++++++++++++++++++++++++++++++++++++ |
814 | Print out the profiles as JavaScript Object Notation for use in a web form. |
815 | ++++++++++++++++++++++++++++++++++++++*/ |
816 | |
817 | void PrintProfilesJSON(void) |
818 | { |
819 | unsigned int i,j; |
820 | |
821 | printf("var routino={ // contains all default Routino options (generated using \"--help-profile-json\").\n"); |
822 | printf("\n"); |
823 | |
824 | printf(" // Default transport type\n"); |
825 | printf(" transport: 'motorcar',\n"); |
826 | printf("\n"); |
827 | |
828 | printf(" // Transport types\n"); |
829 | printf(" transports: {"); |
830 | for(j=0;j<nloaded_profiles;j++) |
831 | printf("%s%s: %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j); |
832 | printf("},\n"); |
833 | printf("\n"); |
834 | |
835 | printf(" // Highway types\n"); |
836 | printf(" highways: {"); |
837 | for(i=1;i<Way_Count;i++) |
838 | printf("%s%s: %d",i==1?"":", ",HighwayName(i),i); |
839 | printf("},\n"); |
840 | printf("\n"); |
841 | |
842 | printf(" // Property types\n"); |
843 | printf(" properties: {"); |
844 | for(i=1;i<Property_Count;i++) |
845 | printf("%s%s: %d",i==1?"":", ",PropertyName(i),i); |
846 | printf("},\n"); |
847 | printf("\n"); |
848 | |
849 | printf(" // Restriction types\n"); |
850 | printf(" restrictions: {oneway: 1, weight: 2, height: 3, width: 4, length: 5},\n"); |
851 | printf("\n"); |
852 | |
853 | printf(" // Allowed highways\n"); |
854 | printf(" profile_highway: {\n"); |
855 | for(i=1;i<Way_Count;i++) |
856 | { |
857 | printf(" %12s: {",HighwayName(i)); |
858 | for(j=0;j<nloaded_profiles;j++) |
859 | printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]); |
860 | printf("}%s\n",i==(Way_Count-1)?"":","); |
861 | } |
862 | printf(" },\n"); |
863 | printf("\n"); |
864 | |
865 | printf(" // Speed limits\n"); |
866 | printf(" profile_speed: {\n"); |
867 | for(i=1;i<Way_Count;i++) |
868 | { |
869 | printf(" %12s: {",HighwayName(i)); |
870 | for(j=0;j<nloaded_profiles;j++) |
871 | printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]); |
872 | printf("}%s\n",i==(Way_Count-1)?"":","); |
873 | } |
874 | printf(" },\n"); |
875 | printf("\n"); |
876 | |
877 | printf(" // Highway properties\n"); |
878 | printf(" profile_property: {\n"); |
879 | for(i=1;i<Property_Count;i++) |
880 | { |
881 | printf(" %12s: {",PropertyName(i)); |
882 | for(j=0;j<nloaded_profiles;j++) |
883 | printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]); |
884 | printf("}%s\n",i==(Property_Count-1)?"":","); |
885 | } |
886 | printf(" },\n"); |
887 | printf("\n"); |
888 | |
889 | printf(" // Restrictions\n"); |
890 | printf(" profile_restrictions: {\n"); |
891 | printf(" %12s: {","oneway"); |
892 | for(j=0;j<nloaded_profiles;j++) |
893 | printf("%s%s: %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway); |
894 | printf("},\n"); |
895 | printf(" %12s: {","weight"); |
896 | for(j=0;j<nloaded_profiles;j++) |
897 | printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight)); |
898 | printf("},\n"); |
899 | printf(" %12s: {","height"); |
900 | for(j=0;j<nloaded_profiles;j++) |
901 | printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height)); |
902 | printf("},\n"); |
903 | printf(" %12s: {","width"); |
904 | for(j=0;j<nloaded_profiles;j++) |
905 | printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width)); |
906 | printf("},\n"); |
907 | printf(" %12s: {","length"); |
908 | for(j=0;j<nloaded_profiles;j++) |
909 | printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length)); |
910 | printf("}\n"); |
911 | printf(" }\n"); |
912 | printf("\n"); |
913 | |
914 | printf("}; // end of routino variable\n"); |
915 | } |
916 | |
917 | |
918 | /*++++++++++++++++++++++++++++++++++++++ |
919 | Print out the profiles as Perl for use in a web CGI. |
920 | ++++++++++++++++++++++++++++++++++++++*/ |
921 | |
922 | void PrintProfilesPerl(void) |
923 | { |
924 | unsigned int i,j; |
925 | |
926 | printf("$routino={ # contains all default Routino options (generated using \"--help-profile-perl\").\n"); |
927 | printf("\n"); |
928 | |
929 | printf(" # Default transport type\n"); |
930 | printf(" transport => 'motorcar',\n"); |
931 | printf("\n"); |
932 | |
933 | printf(" # Transport types\n"); |
934 | printf(" transports => {"); |
935 | for(j=0;j<nloaded_profiles;j++) |
936 | printf("%s%s => %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j); |
937 | printf("},\n"); |
938 | printf("\n"); |
939 | |
940 | printf(" # Highway types\n"); |
941 | printf(" highways => {"); |
942 | for(i=1;i<Way_Count;i++) |
943 | printf("%s%s => %d",i==1?"":", ",HighwayName(i),i); |
944 | printf("},\n"); |
945 | printf("\n"); |
946 | |
947 | printf(" # Property types\n"); |
948 | printf(" properties => {"); |
949 | for(i=1;i<Property_Count;i++) |
950 | printf("%s%s => %d",i==1?"":", ",PropertyName(i),i); |
951 | printf("},\n"); |
952 | printf("\n"); |
953 | |
954 | printf(" # Restriction types\n"); |
955 | printf(" restrictions => {oneway => 1, weight => 2, height => 3, width => 4, length => 5},\n"); |
956 | printf("\n"); |
957 | |
958 | printf(" # Allowed highways\n"); |
959 | printf(" profile_highway => {\n"); |
960 | for(i=1;i<Way_Count;i++) |
961 | { |
962 | printf(" %12s => {",HighwayName(i)); |
963 | for(j=0;j<nloaded_profiles;j++) |
964 | printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]); |
965 | printf("}%s\n",i==(Way_Count-1)?"":","); |
966 | } |
967 | printf(" },\n"); |
968 | printf("\n"); |
969 | |
970 | printf(" # Speed limits\n"); |
971 | printf(" profile_speed => {\n"); |
972 | for(i=1;i<Way_Count;i++) |
973 | { |
974 | printf(" %12s => {",HighwayName(i)); |
975 | for(j=0;j<nloaded_profiles;j++) |
976 | printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]); |
977 | printf("}%s\n",i==(Way_Count-1)?"":","); |
978 | } |
979 | printf(" },\n"); |
980 | printf("\n"); |
981 | |
982 | printf(" # Highway properties\n"); |
983 | printf(" profile_property => {\n"); |
984 | for(i=1;i<Property_Count;i++) |
985 | { |
986 | printf(" %12s => {",PropertyName(i)); |
987 | for(j=0;j<nloaded_profiles;j++) |
988 | printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]); |
989 | printf("}%s\n",i==(Property_Count-1)?"":","); |
990 | } |
991 | printf(" },\n"); |
992 | printf("\n"); |
993 | |
994 | printf(" # Restrictions\n"); |
995 | printf(" profile_restrictions => {\n"); |
996 | printf(" %12s => {","oneway"); |
997 | for(j=0;j<nloaded_profiles;j++) |
998 | printf("%s %s => %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway); |
999 | printf("},\n"); |
1000 | printf(" %12s => {","weight"); |
1001 | for(j=0;j<nloaded_profiles;j++) |
1002 | printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight)); |
1003 | printf("},\n"); |
1004 | printf(" %12s => {","height"); |
1005 | for(j=0;j<nloaded_profiles;j++) |
1006 | printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height)); |
1007 | printf("},\n"); |
1008 | printf(" %12s => {","width"); |
1009 | for(j=0;j<nloaded_profiles;j++) |
1010 | printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width)); |
1011 | printf("},\n"); |
1012 | printf(" %12s => {","length"); |
1013 | for(j=0;j<nloaded_profiles;j++) |
1014 | printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length)); |
1015 | printf("}\n"); |
1016 | printf(" },\n"); |
1017 | printf("\n"); |
1018 | |
1019 | printf("}; # end of routino variable\n"); |
1020 | } |
Properties
Name | Value |
---|---|
cvs:description | Definition of built-in profiles and other functions. |