1 /***************************************
2 $Header: /home/amb/routino/src/RCS/profiles.c,v 1.42 2010/05/29 10:37:12 amb Exp $
4 Load the profiles from a file and the functions for handling them.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
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.
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.
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 ***************************************/
33 #include "functions.h"
36 /*+ The profiles that have been loaded from file. +*/
37 static Profile **loaded_profiles=NULL;
39 /*+ The number of profiles that have been loaded from file. +*/
40 static int nloaded_profiles=0;
43 /* The XML tag processing function prototypes */
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 propertiesType_function(const char *_tag_,int _type_);
54 static int onewayType_function(const char *_tag_,int _type_,const char *obey);
55 static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent);
56 //static int preferencesType_function(const char *_tag_,int _type_);
57 static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent);
58 //static int speedsType_function(const char *_tag_,int _type_);
59 static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph);
62 /* The XML tag definitions */
64 /*+ The speedType type tag. +*/
65 static xmltag speedType_tag=
71 /*+ The speedsType type tag. +*/
72 static xmltag speedsType_tag=
76 {&speedType_tag,NULL}};
78 /*+ The preferenceType type tag. +*/
79 static xmltag preferenceType_tag=
81 2, {"highway","percent"},
82 preferenceType_function,
85 /*+ The preferencesType type tag. +*/
86 static xmltag preferencesType_tag=
90 {&preferenceType_tag,NULL}};
92 /*+ The propertyType type tag. +*/
93 static xmltag propertyType_tag=
95 2, {"type","percent"},
96 propertyType_function,
99 /*+ The onewayType type tag. +*/
100 static xmltag onewayType_tag=
106 /*+ The propertiesType type tag. +*/
107 static xmltag propertiesType_tag=
111 {&propertyType_tag,NULL}};
113 /*+ The weightType type tag. +*/
114 static xmltag weightType_tag=
120 /*+ The heightType type tag. +*/
121 static xmltag heightType_tag=
127 /*+ The widthType type tag. +*/
128 static xmltag widthType_tag=
134 /*+ The lengthType type tag. +*/
135 static xmltag lengthType_tag=
141 /*+ The restrictionsType type tag. +*/
142 static xmltag restrictionsType_tag=
146 {&onewayType_tag,&weightType_tag,&heightType_tag,&widthType_tag,&lengthType_tag,NULL}};
148 /*+ The profileType type tag. +*/
149 static xmltag profileType_tag=
151 2, {"name","transport"},
152 profileType_function,
153 {&speedsType_tag,&preferencesType_tag,&propertiesType_tag,&restrictionsType_tag,NULL}};
155 /*+ The RoutinoProfilesType type tag. +*/
156 static xmltag RoutinoProfilesType_tag=
160 {&profileType_tag,NULL}};
162 /*+ The xmlDeclaration type tag. +*/
163 static xmltag xmlDeclaration_tag=
165 2, {"version","encoding"},
170 /*+ The complete set of tags at the top level. +*/
171 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL};
174 /* The XML tag processing functions */
177 /*++++++++++++++++++++++++++++++++++++++
178 The function that is called when the speedType XSD type is seen
180 int speedType_function Returns 0 if no error occured or something else otherwise.
182 const char *_tag_ Set to the name of the element tag that triggered this function call.
184 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
186 const char *highway The contents of the 'highway' attribute (or NULL if not defined).
188 const char *kph The contents of the 'kph' attribute (or NULL if not defined).
189 ++++++++++++++++++++++++++++++++++++++*/
191 static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph)
193 if(_type_&XMLPARSE_TAG_START)
198 XMLPARSE_ASSERT_STRING(_tag_,highway);
200 highwaytype=HighwayType(highway);
202 if(highwaytype==Way_Count)
203 XMLPARSE_INVALID(_tag_,highway);
205 XMLPARSE_ASSERT_FLOATING(_tag_,kph,speed);
207 loaded_profiles[nloaded_profiles-1]->speed[highwaytype]=kph_to_speed(speed);
214 /*++++++++++++++++++++++++++++++++++++++
215 The function that is called when the speedsType XSD type is seen
217 int speedsType_function Returns 0 if no error occured or something else otherwise.
219 const char *_tag_ Set to the name of the element tag that triggered this function call.
221 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
222 ++++++++++++++++++++++++++++++++++++++*/
224 //static int speedsType_function(const char *_tag_,int _type_)
230 /*++++++++++++++++++++++++++++++++++++++
231 The function that is called when the preferenceType XSD type is seen
233 int preferenceType_function Returns 0 if no error occured or something else otherwise.
235 const char *_tag_ Set to the name of the element tag that triggered this function call.
237 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
239 const char *highway The contents of the 'highway' attribute (or NULL if not defined).
241 const char *percent The contents of the 'percent' attribute (or NULL if not defined).
242 ++++++++++++++++++++++++++++++++++++++*/
244 static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent)
246 if(_type_&XMLPARSE_TAG_START)
251 XMLPARSE_ASSERT_STRING(_tag_,highway);
253 highwaytype=HighwayType(highway);
255 if(highwaytype==Way_Count)
256 XMLPARSE_INVALID(_tag_,highway);
258 XMLPARSE_ASSERT_FLOATING(_tag_,percent,p);
260 loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=p;
267 /*++++++++++++++++++++++++++++++++++++++
268 The function that is called when the preferencesType XSD type is seen
270 int preferencesType_function Returns 0 if no error occured or something else otherwise.
272 const char *_tag_ Set to the name of the element tag that triggered this function call.
274 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
275 ++++++++++++++++++++++++++++++++++++++*/
277 //static int preferencesType_function(const char *_tag_,int _type_)
283 /*++++++++++++++++++++++++++++++++++++++
284 The function that is called when the propertyType XSD type is seen
286 int propertyType_function Returns 0 if no error occured or something else otherwise.
288 const char *_tag_ Set to the name of the element tag that triggered this function call.
290 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
292 const char *type The contents of the 'type' attribute (or NULL if not defined).
294 const char *percent The contents of the 'percent' attribute (or NULL if not defined).
295 ++++++++++++++++++++++++++++++++++++++*/
297 static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent)
299 if(_type_&XMLPARSE_TAG_START)
304 XMLPARSE_ASSERT_STRING(_tag_,type);
306 property=PropertyType(type);
308 if(property==Property_Count)
309 XMLPARSE_INVALID(_tag_,type);
311 XMLPARSE_ASSERT_FLOATING(_tag_,percent,p);
313 loaded_profiles[nloaded_profiles-1]->props_yes[property]=p;
320 /*++++++++++++++++++++++++++++++++++++++
321 The function that is called when the onewayType XSD type is seen
323 int onewayType_function Returns 0 if no error occured or something else otherwise.
325 const char *_tag_ Set to the name of the element tag that triggered this function call.
327 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
329 const char *obey The contents of the 'obey' attribute (or NULL if not defined).
330 ++++++++++++++++++++++++++++++++++++++*/
332 static int onewayType_function(const char *_tag_,int _type_,const char *obey)
334 if(_type_&XMLPARSE_TAG_START)
338 XMLPARSE_ASSERT_INTEGER(_tag_,obey,o);
340 loaded_profiles[nloaded_profiles-1]->oneway=!!o;
347 /*++++++++++++++++++++++++++++++++++++++
348 The function that is called when the propertiesType XSD type is seen
350 int propertiesType_function Returns 0 if no error occured or something else otherwise.
352 const char *_tag_ Set to the name of the element tag that triggered this function call.
354 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
355 ++++++++++++++++++++++++++++++++++++++*/
357 //static int propertiesType_function(const char *_tag_,int _type_)
363 /*++++++++++++++++++++++++++++++++++++++
364 The function that is called when the weightType XSD type is seen
366 int weightType_function Returns 0 if no error occured or something else otherwise.
368 const char *_tag_ Set to the name of the element tag that triggered this function call.
370 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
372 const char *limit The contents of the 'limit' attribute (or NULL if not defined).
373 ++++++++++++++++++++++++++++++++++++++*/
375 static int weightType_function(const char *_tag_,int _type_,const char *limit)
377 if(_type_&XMLPARSE_TAG_START)
381 XMLPARSE_ASSERT_FLOATING(_tag_,limit,l);
383 loaded_profiles[nloaded_profiles-1]->weight=tonnes_to_weight(l);
390 /*++++++++++++++++++++++++++++++++++++++
391 The function that is called when the heightType XSD type is seen
393 int heightType_function Returns 0 if no error occured or something else otherwise.
395 const char *_tag_ Set to the name of the element tag that triggered this function call.
397 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 const char *limit The contents of the 'limit' attribute (or NULL if not defined).
400 ++++++++++++++++++++++++++++++++++++++*/
402 static int heightType_function(const char *_tag_,int _type_,const char *limit)
404 if(_type_&XMLPARSE_TAG_START)
408 XMLPARSE_ASSERT_FLOATING(_tag_,limit,l);
410 loaded_profiles[nloaded_profiles-1]->height=metres_to_height(l);
417 /*++++++++++++++++++++++++++++++++++++++
418 The function that is called when the widthType XSD type is seen
420 int widthType_function Returns 0 if no error occured or something else otherwise.
422 const char *_tag_ Set to the name of the element tag that triggered this function call.
424 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
426 const char *limit The contents of the 'limit' attribute (or NULL if not defined).
427 ++++++++++++++++++++++++++++++++++++++*/
429 static int widthType_function(const char *_tag_,int _type_,const char *limit)
431 if(_type_&XMLPARSE_TAG_START)
435 XMLPARSE_ASSERT_FLOATING(_tag_,limit,l);
437 loaded_profiles[nloaded_profiles-1]->width=metres_to_width(l);
444 /*++++++++++++++++++++++++++++++++++++++
445 The function that is called when the lengthType XSD type is seen
447 int lengthType_function Returns 0 if no error occured or something else otherwise.
449 const char *_tag_ Set to the name of the element tag that triggered this function call.
451 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
453 const char *limit The contents of the 'limit' attribute (or NULL if not defined).
454 ++++++++++++++++++++++++++++++++++++++*/
456 static int lengthType_function(const char *_tag_,int _type_,const char *limit)
458 if(_type_&XMLPARSE_TAG_START)
462 XMLPARSE_ASSERT_FLOATING(_tag_,limit,l);
464 loaded_profiles[nloaded_profiles-1]->length=metres_to_length(l);
471 /*++++++++++++++++++++++++++++++++++++++
472 The function that is called when the restrictionsType XSD type is seen
474 int restrictionsType_function Returns 0 if no error occured or something else otherwise.
476 const char *_tag_ Set to the name of the element tag that triggered this function call.
478 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
479 ++++++++++++++++++++++++++++++++++++++*/
481 //static int restrictionsType_function(const char *_tag_,int _type_)
487 /*++++++++++++++++++++++++++++++++++++++
488 The function that is called when the profileType XSD type is seen
490 int profileType_function Returns 0 if no error occured or something else otherwise.
492 const char *_tag_ Set to the name of the element tag that triggered this function call.
494 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
496 const char *name The contents of the 'name' attribute (or NULL if not defined).
498 const char *transport The contents of the 'transport' attribute (or NULL if not defined).
499 ++++++++++++++++++++++++++++++++++++++*/
501 static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport)
503 if(_type_&XMLPARSE_TAG_START)
505 Transport transporttype;
508 XMLPARSE_ASSERT_STRING(_tag_,name);
509 XMLPARSE_ASSERT_STRING(_tag_,transport);
511 for(i=0;i<nloaded_profiles;i++)
512 if(!strcmp(name,loaded_profiles[i]->name))
513 XMLPARSE_MESSAGE(_tag_,"profile name must be unique");
515 transporttype=TransportType(transport);
517 if(transporttype==Transport_None)
518 XMLPARSE_INVALID(_tag_,transport);
520 if((nloaded_profiles%16)==0)
521 loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*));
525 loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile));
527 loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name);
528 loaded_profiles[nloaded_profiles-1]->transport=transporttype;
535 /*++++++++++++++++++++++++++++++++++++++
536 The function that is called when the RoutinoProfilesType XSD type is seen
538 int RoutinoProfilesType_function Returns 0 if no error occured or something else otherwise.
540 const char *_tag_ Set to the name of the element tag that triggered this function call.
542 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
543 ++++++++++++++++++++++++++++++++++++++*/
545 //static int RoutinoProfilesType_function(const char *_tag_,int _type_)
551 /*++++++++++++++++++++++++++++++++++++++
552 The function that is called when the XML declaration is seen
554 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
556 const char *_tag_ Set to the name of the element tag that triggered this function call.
558 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
560 const char *version The contents of the 'version' attribute (or NULL if not defined).
562 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
563 ++++++++++++++++++++++++++++++++++++++*/
565 //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
571 /*++++++++++++++++++++++++++++++++++++++
572 The XML profile parser.
574 int ParseXMLProfiles Returns 0 if OK or something else in case of an error.
576 const char *filename The name of the file to read.
577 ++++++++++++++++++++++++++++++++++++++*/
579 int ParseXMLProfiles(const char *filename)
583 if(!ExistsFile(filename))
585 fprintf(stderr,"Error: Specified profiles file '%s' does not exist.\n",filename);
589 FILE *file=fopen(filename,"r");
593 fprintf(stderr,"Error: Cannot open profiles file '%s' for reading.\n",filename);
597 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME);
605 for(i=0;i<nloaded_profiles;i++)
606 free(loaded_profiles[i]);
607 free(loaded_profiles);
618 /*++++++++++++++++++++++++++++++++++++++
619 Get the profile for a type of transport.
621 Profile *GetProfile Returns a pointer to the profile.
623 const char *name The name of the profile.
624 ++++++++++++++++++++++++++++++++++++++*/
626 Profile *GetProfile(const char *name)
630 for(i=0;i<nloaded_profiles;i++)
631 if(!strcmp(loaded_profiles[i]->name,name))
632 return(loaded_profiles[i]);
638 /*++++++++++++++++++++++++++++++++++++++
639 Update a profile with highway preference scaling factor.
641 int UpdateProfile Returns 1 in case of a problem.
643 Profile *profile The profile to be updated.
645 Ways *ways The set of ways to use.
646 ++++++++++++++++++++++++++++++++++++++*/
648 int UpdateProfile(Profile *profile,Ways *ways)
653 /* Fix up the allowed transport types. */
655 profile->allow=ALLOWED(profile->transport);
657 if(!(profile->allow & ways->allow))
660 /* Normalise the highway preferences into the range 0 -> 1 */
662 for(i=1;i<Way_Count;i++)
664 if(profile->highway[i]<0)
665 profile->highway[i]=0;
667 if(profile->highway[i]>hmax)
668 hmax=profile->highway[i];
674 for(i=1;i<Way_Count;i++)
675 profile->highway[i]/=hmax;
677 /* Normalise the property preferences into the range 0 -> 2 */
679 for(i=1;i<Property_Count;i++)
681 if(profile->props_yes[i]<0)
682 profile->props_yes[i]=0;
684 if(profile->props_yes[i]>100)
685 profile->props_yes[i]=100;
687 profile->props_yes[i]/=50;
688 profile->props_no [i] =2-profile->props_yes[i];
691 /* Find the fastest preferred speed */
693 profile->max_speed=0;
695 for(i=1;i<Way_Count;i++)
696 if(profile->speed[i]>profile->max_speed)
697 profile->max_speed=profile->speed[i];
699 if(profile->max_speed==0)
702 /* Find the most preferred property combination */
704 profile->max_pref=1; /* since highway prefs were normalised to 1 */
706 for(i=1;i<Property_Count;i++)
707 if(ways->props & PROPERTIES(i))
709 if(profile->props_yes[i]>profile->props_no[i])
710 profile->max_pref*=profile->props_yes[i];
712 profile->max_pref*=profile->props_no[i];
719 /*++++++++++++++++++++++++++++++++++++++
722 const Profile *profile The profile to print.
723 ++++++++++++++++++++++++++++++++++++++*/
725 void PrintProfile(const Profile *profile)
729 printf("Profile\n=======\n");
733 printf("Transport: %s\n",TransportName(profile->transport));
737 for(i=1;i<Way_Count;i++)
738 printf("Highway %-12s: %3d%%\n",HighwayName(i),(int)profile->highway[i]);
742 for(i=1;i<Way_Count;i++)
743 if(profile->highway[i])
744 printf("Speed on %-12s: %3d km/h / %2.0f mph\n",HighwayName(i),profile->speed[i],(double)profile->speed[i]/1.6);
748 for(i=1;i<Property_Count;i++)
749 printf("Highway property %-12s: %3d%%\n",PropertyName(i),(int)profile->props_yes[i]);
753 printf("Obey one-way : %s\n",profile->oneway?"yes":"no");
754 printf("Minimum weight: %.1f tonnes\n",weight_to_tonnes(profile->weight));
755 printf("Minimum height: %.1f metres\n",height_to_metres(profile->height));
756 printf("Minimum width : %.1f metres\n",width_to_metres(profile->width));
757 printf("Minimum length: %.1f metres\n",length_to_metres(profile->length));
761 /*++++++++++++++++++++++++++++++++++++++
762 Print out the profiles as XML for use as program input.
763 ++++++++++++++++++++++++++++++++++++++*/
765 void PrintProfilesXML(void)
770 printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
773 printf("<routino-profiles xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"routino-profiles.xsd\">\n");
776 for(j=0;j<nloaded_profiles;j++)
778 printf(" <profile name=\"%s\" transport=\"%s\">\n",loaded_profiles[j]->name,TransportName(loaded_profiles[j]->transport));
780 printf(" <speeds>\n");
781 for(i=1;i<Way_Count;i++)
782 printf(" <speed highway=\"%s\"%s kph=\"%d\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->speed[i]);
783 printf(" </speeds>\n");
785 printf(" <preferences>\n");
786 for(i=1;i<Way_Count;i++)
787 printf(" <preference highway=\"%s\"%s percent=\"%.0f\" />\n",HighwayName(i),padding+3+strlen(HighwayName(i)),loaded_profiles[j]->highway[i]);
788 printf(" </preferences>\n");
790 printf(" <properties>\n");
791 for(i=1;i<Property_Count;i++)
792 printf(" <property type=\"%s\"%s percent=\"%.0f\" />\n",PropertyName(i),padding+6+strlen(PropertyName(i)),loaded_profiles[j]->props_yes[i]);
793 printf(" </properties>\n");
795 printf(" <restrictions>\n");
796 printf(" <oneway obey=\"%d\" /> \n",loaded_profiles[j]->oneway);
797 printf(" <weight limit=\"%.1f\" />\n",weight_to_tonnes(loaded_profiles[j]->weight));
798 printf(" <height limit=\"%.1f\" />\n",height_to_metres(loaded_profiles[j]->height));
799 printf(" <width limit=\"%.1f\" />\n",width_to_metres(loaded_profiles[j]->width));
800 printf(" <length limit=\"%.1f\" />\n",length_to_metres(loaded_profiles[j]->length));
801 printf(" </restrictions>\n");
803 printf(" </profile>\n");
807 printf("</routino-profiles>\n");
811 /*++++++++++++++++++++++++++++++++++++++
812 Print out the profiles as JavaScript Object Notation for use in a web form.
813 ++++++++++++++++++++++++++++++++++++++*/
815 void PrintProfilesJSON(void)
819 printf("var routino={ // contains all default Routino options (generated using \"--help-profile-json\").\n");
822 printf(" // Default transport type\n");
823 printf(" transport: 'motorcar',\n");
826 printf(" // Transport types\n");
827 printf(" transports: {");
828 for(j=0;j<nloaded_profiles;j++)
829 printf("%s%s: %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j);
833 printf(" // Highway types\n");
834 printf(" highways: {");
835 for(i=1;i<Way_Count;i++)
836 printf("%s%s: %d",i==1?"":", ",HighwayName(i),i);
840 printf(" // Property types\n");
841 printf(" properties: {");
842 for(i=1;i<Property_Count;i++)
843 printf("%s%s: %d",i==1?"":", ",PropertyName(i),i);
847 printf(" // Restriction types\n");
848 printf(" restrictions: {oneway: 1, weight: 2, height: 3, width: 4, length: 5},\n");
851 printf(" // Allowed highways\n");
852 printf(" profile_highway: {\n");
853 for(i=1;i<Way_Count;i++)
855 printf(" %12s: {",HighwayName(i));
856 for(j=0;j<nloaded_profiles;j++)
857 printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
858 printf("}%s\n",i==(Way_Count-1)?"":",");
863 printf(" // Speed limits\n");
864 printf(" profile_speed: {\n");
865 for(i=1;i<Way_Count;i++)
867 printf(" %12s: {",HighwayName(i));
868 for(j=0;j<nloaded_profiles;j++)
869 printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
870 printf("}%s\n",i==(Way_Count-1)?"":",");
875 printf(" // Highway properties\n");
876 printf(" profile_property: {\n");
877 for(i=1;i<Property_Count;i++)
879 printf(" %12s: {",PropertyName(i));
880 for(j=0;j<nloaded_profiles;j++)
881 printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
882 printf("}%s\n",i==(Property_Count-1)?"":",");
887 printf(" // Restrictions\n");
888 printf(" profile_restrictions: {\n");
889 printf(" %12s: {","oneway");
890 for(j=0;j<nloaded_profiles;j++)
891 printf("%s%s: %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
893 printf(" %12s: {","weight");
894 for(j=0;j<nloaded_profiles;j++)
895 printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
897 printf(" %12s: {","height");
898 for(j=0;j<nloaded_profiles;j++)
899 printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
901 printf(" %12s: {","width");
902 for(j=0;j<nloaded_profiles;j++)
903 printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
905 printf(" %12s: {","length");
906 for(j=0;j<nloaded_profiles;j++)
907 printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
912 printf("}; // end of routino variable\n");
916 /*++++++++++++++++++++++++++++++++++++++
917 Print out the profiles as Perl for use in a web CGI.
918 ++++++++++++++++++++++++++++++++++++++*/
920 void PrintProfilesPerl(void)
924 printf("$routino={ # contains all default Routino options (generated using \"--help-profile-perl\").\n");
927 printf(" # Default transport type\n");
928 printf(" transport => 'motorcar',\n");
931 printf(" # Transport types\n");
932 printf(" transports => {");
933 for(j=0;j<nloaded_profiles;j++)
934 printf("%s%s => %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j);
938 printf(" # Highway types\n");
939 printf(" highways => {");
940 for(i=1;i<Way_Count;i++)
941 printf("%s%s => %d",i==1?"":", ",HighwayName(i),i);
945 printf(" # Property types\n");
946 printf(" properties => {");
947 for(i=1;i<Property_Count;i++)
948 printf("%s%s => %d",i==1?"":", ",PropertyName(i),i);
952 printf(" # Restriction types\n");
953 printf(" restrictions => {oneway => 1, weight => 2, height => 3, width => 4, length => 5},\n");
956 printf(" # Allowed highways\n");
957 printf(" profile_highway => {\n");
958 for(i=1;i<Way_Count;i++)
960 printf(" %12s => {",HighwayName(i));
961 for(j=0;j<nloaded_profiles;j++)
962 printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
963 printf("}%s\n",i==(Way_Count-1)?"":",");
968 printf(" # Speed limits\n");
969 printf(" profile_speed => {\n");
970 for(i=1;i<Way_Count;i++)
972 printf(" %12s => {",HighwayName(i));
973 for(j=0;j<nloaded_profiles;j++)
974 printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
975 printf("}%s\n",i==(Way_Count-1)?"":",");
980 printf(" # Highway properties\n");
981 printf(" profile_property => {\n");
982 for(i=1;i<Property_Count;i++)
984 printf(" %12s => {",PropertyName(i));
985 for(j=0;j<nloaded_profiles;j++)
986 printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
987 printf("}%s\n",i==(Property_Count-1)?"":",");
992 printf(" # Restrictions\n");
993 printf(" profile_restrictions => {\n");
994 printf(" %12s => {","oneway");
995 for(j=0;j<nloaded_profiles;j++)
996 printf("%s %s => %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
998 printf(" %12s => {","weight");
999 for(j=0;j<nloaded_profiles;j++)
1000 printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
1002 printf(" %12s => {","height");
1003 for(j=0;j<nloaded_profiles;j++)
1004 printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
1006 printf(" %12s => {","width");
1007 for(j=0;j<nloaded_profiles;j++)
1008 printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
1010 printf(" %12s => {","length");
1011 for(j=0;j<nloaded_profiles;j++)
1012 printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
1017 printf("}; # end of routino variable\n");