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