Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /branches/libroutino/src/profiles.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1711 - (show annotations) (download) (as text)
Tue Jun 16 19:05:31 2015 UTC (9 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 34467 byte(s)
Audit the use of file static variables to make sure that there are no
implicit assumptions about initialisation conditions that would be
wrong for library usage.  Fix problems and add comments for clarity.

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

Properties

Name Value
cvs:description Definition of built-in profiles and other functions.