Routino SVN Repository Browser

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

ViewVC logotype

Contents of /branches/destination-access/src/profiles.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1861 - (show annotations) (download) (as text)
Thu Feb 25 18:53:35 2016 UTC (9 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 36305 byte(s)
Merge from trunk r1850 and r1852 to r1856 (profiles, translations, documentation, extras).

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

Properties

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