Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /branches/destination-access/src/profiles.c
Parent Directory
|
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)
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. |