Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/profiles.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 622 - (show annotations) (download) (as text)
Sat Feb 5 15:41:48 2011 UTC (14 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 33418 byte(s)
Include the option to obey turn restrictions in the profile for each transport
type.

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

Properties

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