Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/profiles.c
Parent Directory
|
Revision Log
Revision 410 -
(show annotations)
(download)
(as text)
Sat May 29 10:37:12 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 31266 byte(s)
Sat May 29 10:37:12 2010 UTC (14 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 31266 byte(s)
Stricter check on specified profile before routing.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/profiles.c,v 1.42 2010-05-29 10:37:12 amb Exp $ |
3 | |
4 | Load the profiles from a file and the functions for handling them. |
5 | |
6 | Part of the Routino routing software. |
7 | ******************/ /****************** |
8 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | |
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. |
14 | |
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. |
19 | |
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 | ***************************************/ |
23 | |
24 | |
25 | #include <stdio.h> |
26 | #include <string.h> |
27 | #include <stdlib.h> |
28 | |
29 | #include "profiles.h" |
30 | #include "types.h" |
31 | #include "ways.h" |
32 | #include "xmlparse.h" |
33 | #include "functions.h" |
34 | |
35 | |
36 | /*+ The profiles that have been loaded from file. +*/ |
37 | static Profile **loaded_profiles=NULL; |
38 | |
39 | /*+ The number of profiles that have been loaded from file. +*/ |
40 | static int nloaded_profiles=0; |
41 | |
42 | |
43 | /* The XML tag processing function prototypes */ |
44 | |
45 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); |
46 | //static int RoutinoProfilesType_function(const char *_tag_,int _type_); |
47 | static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport); |
48 | //static int restrictionsType_function(const char *_tag_,int _type_); |
49 | static int lengthType_function(const char *_tag_,int _type_,const char *limit); |
50 | static int widthType_function(const char *_tag_,int _type_,const char *limit); |
51 | static int heightType_function(const char *_tag_,int _type_,const char *limit); |
52 | static int weightType_function(const char *_tag_,int _type_,const char *limit); |
53 | //static int 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); |
60 | |
61 | |
62 | /* The XML tag definitions */ |
63 | |
64 | /*+ The speedType type tag. +*/ |
65 | static xmltag speedType_tag= |
66 | {"speed", |
67 | 2, {"highway","kph"}, |
68 | speedType_function, |
69 | {NULL}}; |
70 | |
71 | /*+ The speedsType type tag. +*/ |
72 | static xmltag speedsType_tag= |
73 | {"speeds", |
74 | 0, {NULL}, |
75 | NULL, |
76 | {&speedType_tag,NULL}}; |
77 | |
78 | /*+ The preferenceType type tag. +*/ |
79 | static xmltag preferenceType_tag= |
80 | {"preference", |
81 | 2, {"highway","percent"}, |
82 | preferenceType_function, |
83 | {NULL}}; |
84 | |
85 | /*+ The preferencesType type tag. +*/ |
86 | static xmltag preferencesType_tag= |
87 | {"preferences", |
88 | 0, {NULL}, |
89 | NULL, |
90 | {&preferenceType_tag,NULL}}; |
91 | |
92 | /*+ The propertyType type tag. +*/ |
93 | static xmltag propertyType_tag= |
94 | {"property", |
95 | 2, {"type","percent"}, |
96 | propertyType_function, |
97 | {NULL}}; |
98 | |
99 | /*+ The onewayType type tag. +*/ |
100 | static xmltag onewayType_tag= |
101 | {"oneway", |
102 | 1, {"obey"}, |
103 | onewayType_function, |
104 | {NULL}}; |
105 | |
106 | /*+ The propertiesType type tag. +*/ |
107 | static xmltag propertiesType_tag= |
108 | {"properties", |
109 | 0, {NULL}, |
110 | NULL, |
111 | {&propertyType_tag,NULL}}; |
112 | |
113 | /*+ The weightType type tag. +*/ |
114 | static xmltag weightType_tag= |
115 | {"weight", |
116 | 1, {"limit"}, |
117 | weightType_function, |
118 | {NULL}}; |
119 | |
120 | /*+ The heightType type tag. +*/ |
121 | static xmltag heightType_tag= |
122 | {"height", |
123 | 1, {"limit"}, |
124 | heightType_function, |
125 | {NULL}}; |
126 | |
127 | /*+ The widthType type tag. +*/ |
128 | static xmltag widthType_tag= |
129 | {"width", |
130 | 1, {"limit"}, |
131 | widthType_function, |
132 | {NULL}}; |
133 | |
134 | /*+ The lengthType type tag. +*/ |
135 | static xmltag lengthType_tag= |
136 | {"length", |
137 | 1, {"limit"}, |
138 | lengthType_function, |
139 | {NULL}}; |
140 | |
141 | /*+ The restrictionsType type tag. +*/ |
142 | static xmltag restrictionsType_tag= |
143 | {"restrictions", |
144 | 0, {NULL}, |
145 | NULL, |
146 | {&onewayType_tag,&weightType_tag,&heightType_tag,&widthType_tag,&lengthType_tag,NULL}}; |
147 | |
148 | /*+ The profileType type tag. +*/ |
149 | static xmltag profileType_tag= |
150 | {"profile", |
151 | 2, {"name","transport"}, |
152 | profileType_function, |
153 | {&speedsType_tag,&preferencesType_tag,&propertiesType_tag,&restrictionsType_tag,NULL}}; |
154 | |
155 | /*+ The RoutinoProfilesType type tag. +*/ |
156 | static xmltag RoutinoProfilesType_tag= |
157 | {"routino-profiles", |
158 | 0, {NULL}, |
159 | NULL, |
160 | {&profileType_tag,NULL}}; |
161 | |
162 | /*+ The xmlDeclaration type tag. +*/ |
163 | static xmltag xmlDeclaration_tag= |
164 | {"xml", |
165 | 2, {"version","encoding"}, |
166 | NULL, |
167 | {NULL}}; |
168 | |
169 | |
170 | /*+ The complete set of tags at the top level. +*/ |
171 | static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL}; |
172 | |
173 | |
174 | /* The XML tag processing functions */ |
175 | |
176 | |
177 | /*++++++++++++++++++++++++++++++++++++++ |
178 | The function that is called when the speedType XSD type is seen |
179 | |
180 | int speedType_function Returns 0 if no error occured or something else otherwise. |
181 | |
182 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
183 | |
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. |
185 | |
186 | const char *highway The contents of the 'highway' attribute (or NULL if not defined). |
187 | |
188 | const char *kph The contents of the 'kph' attribute (or NULL if not defined). |
189 | ++++++++++++++++++++++++++++++++++++++*/ |
190 | |
191 | static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph) |
192 | { |
193 | if(_type_&XMLPARSE_TAG_START) |
194 | { |
195 | double speed; |
196 | Highway highwaytype; |
197 | |
198 | XMLPARSE_ASSERT_STRING(_tag_,highway); |
199 | |
200 | highwaytype=HighwayType(highway); |
201 | |
202 | if(highwaytype==Way_Count) |
203 | XMLPARSE_INVALID(_tag_,highway); |
204 | |
205 | XMLPARSE_ASSERT_FLOATING(_tag_,kph,speed); |
206 | |
207 | loaded_profiles[nloaded_profiles-1]->speed[highwaytype]=kph_to_speed(speed); |
208 | } |
209 | |
210 | return(0); |
211 | } |
212 | |
213 | |
214 | /*++++++++++++++++++++++++++++++++++++++ |
215 | The function that is called when the speedsType XSD type is seen |
216 | |
217 | int speedsType_function Returns 0 if no error occured or something else otherwise. |
218 | |
219 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
220 | |
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 | ++++++++++++++++++++++++++++++++++++++*/ |
223 | |
224 | //static int speedsType_function(const char *_tag_,int _type_) |
225 | //{ |
226 | // return(0); |
227 | //} |
228 | |
229 | |
230 | /*++++++++++++++++++++++++++++++++++++++ |
231 | The function that is called when the preferenceType XSD type is seen |
232 | |
233 | int preferenceType_function Returns 0 if no error occured or something else otherwise. |
234 | |
235 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
236 | |
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. |
238 | |
239 | const char *highway The contents of the 'highway' attribute (or NULL if not defined). |
240 | |
241 | const char *percent The contents of the 'percent' attribute (or NULL if not defined). |
242 | ++++++++++++++++++++++++++++++++++++++*/ |
243 | |
244 | static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent) |
245 | { |
246 | if(_type_&XMLPARSE_TAG_START) |
247 | { |
248 | Highway highwaytype; |
249 | double p; |
250 | |
251 | XMLPARSE_ASSERT_STRING(_tag_,highway); |
252 | |
253 | highwaytype=HighwayType(highway); |
254 | |
255 | if(highwaytype==Way_Count) |
256 | XMLPARSE_INVALID(_tag_,highway); |
257 | |
258 | XMLPARSE_ASSERT_FLOATING(_tag_,percent,p); |
259 | |
260 | loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=p; |
261 | } |
262 | |
263 | return(0); |
264 | } |
265 | |
266 | |
267 | /*++++++++++++++++++++++++++++++++++++++ |
268 | The function that is called when the preferencesType XSD type is seen |
269 | |
270 | int preferencesType_function Returns 0 if no error occured or something else otherwise. |
271 | |
272 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
273 | |
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 | ++++++++++++++++++++++++++++++++++++++*/ |
276 | |
277 | //static int preferencesType_function(const char *_tag_,int _type_) |
278 | //{ |
279 | // return(0); |
280 | //} |
281 | |
282 | |
283 | /*++++++++++++++++++++++++++++++++++++++ |
284 | The function that is called when the propertyType XSD type is seen |
285 | |
286 | int propertyType_function Returns 0 if no error occured or something else otherwise. |
287 | |
288 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
289 | |
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. |
291 | |
292 | const char *type The contents of the 'type' attribute (or NULL if not defined). |
293 | |
294 | const char *percent The contents of the 'percent' attribute (or NULL if not defined). |
295 | ++++++++++++++++++++++++++++++++++++++*/ |
296 | |
297 | static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent) |
298 | { |
299 | if(_type_&XMLPARSE_TAG_START) |
300 | { |
301 | Property property; |
302 | double p; |
303 | |
304 | XMLPARSE_ASSERT_STRING(_tag_,type); |
305 | |
306 | property=PropertyType(type); |
307 | |
308 | if(property==Property_Count) |
309 | XMLPARSE_INVALID(_tag_,type); |
310 | |
311 | XMLPARSE_ASSERT_FLOATING(_tag_,percent,p); |
312 | |
313 | loaded_profiles[nloaded_profiles-1]->props_yes[property]=p; |
314 | } |
315 | |
316 | return(0); |
317 | } |
318 | |
319 | |
320 | /*++++++++++++++++++++++++++++++++++++++ |
321 | The function that is called when the onewayType XSD type is seen |
322 | |
323 | int onewayType_function Returns 0 if no error occured or something else otherwise. |
324 | |
325 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
326 | |
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. |
328 | |
329 | const char *obey The contents of the 'obey' attribute (or NULL if not defined). |
330 | ++++++++++++++++++++++++++++++++++++++*/ |
331 | |
332 | static int onewayType_function(const char *_tag_,int _type_,const char *obey) |
333 | { |
334 | if(_type_&XMLPARSE_TAG_START) |
335 | { |
336 | int o; |
337 | |
338 | XMLPARSE_ASSERT_INTEGER(_tag_,obey,o); |
339 | |
340 | loaded_profiles[nloaded_profiles-1]->oneway=!!o; |
341 | } |
342 | |
343 | return(0); |
344 | } |
345 | |
346 | |
347 | /*++++++++++++++++++++++++++++++++++++++ |
348 | The function that is called when the propertiesType XSD type is seen |
349 | |
350 | int propertiesType_function Returns 0 if no error occured or something else otherwise. |
351 | |
352 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
353 | |
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 | ++++++++++++++++++++++++++++++++++++++*/ |
356 | |
357 | //static int propertiesType_function(const char *_tag_,int _type_) |
358 | //{ |
359 | // return(0); |
360 | //} |
361 | |
362 | |
363 | /*++++++++++++++++++++++++++++++++++++++ |
364 | The function that is called when the weightType XSD type is seen |
365 | |
366 | int weightType_function Returns 0 if no error occured or something else otherwise. |
367 | |
368 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
369 | |
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. |
371 | |
372 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
373 | ++++++++++++++++++++++++++++++++++++++*/ |
374 | |
375 | static int weightType_function(const char *_tag_,int _type_,const char *limit) |
376 | { |
377 | if(_type_&XMLPARSE_TAG_START) |
378 | { |
379 | double l; |
380 | |
381 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
382 | |
383 | loaded_profiles[nloaded_profiles-1]->weight=tonnes_to_weight(l); |
384 | } |
385 | |
386 | return(0); |
387 | } |
388 | |
389 | |
390 | /*++++++++++++++++++++++++++++++++++++++ |
391 | The function that is called when the heightType XSD type is seen |
392 | |
393 | int heightType_function Returns 0 if no error occured or something else otherwise. |
394 | |
395 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
396 | |
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. |
398 | |
399 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
400 | ++++++++++++++++++++++++++++++++++++++*/ |
401 | |
402 | static int heightType_function(const char *_tag_,int _type_,const char *limit) |
403 | { |
404 | if(_type_&XMLPARSE_TAG_START) |
405 | { |
406 | double l; |
407 | |
408 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
409 | |
410 | loaded_profiles[nloaded_profiles-1]->height=metres_to_height(l); |
411 | } |
412 | |
413 | return(0); |
414 | } |
415 | |
416 | |
417 | /*++++++++++++++++++++++++++++++++++++++ |
418 | The function that is called when the widthType XSD type is seen |
419 | |
420 | int widthType_function Returns 0 if no error occured or something else otherwise. |
421 | |
422 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
423 | |
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. |
425 | |
426 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
427 | ++++++++++++++++++++++++++++++++++++++*/ |
428 | |
429 | static int widthType_function(const char *_tag_,int _type_,const char *limit) |
430 | { |
431 | if(_type_&XMLPARSE_TAG_START) |
432 | { |
433 | double l; |
434 | |
435 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
436 | |
437 | loaded_profiles[nloaded_profiles-1]->width=metres_to_width(l); |
438 | } |
439 | |
440 | return(0); |
441 | } |
442 | |
443 | |
444 | /*++++++++++++++++++++++++++++++++++++++ |
445 | The function that is called when the lengthType XSD type is seen |
446 | |
447 | int lengthType_function Returns 0 if no error occured or something else otherwise. |
448 | |
449 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
450 | |
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. |
452 | |
453 | const char *limit The contents of the 'limit' attribute (or NULL if not defined). |
454 | ++++++++++++++++++++++++++++++++++++++*/ |
455 | |
456 | static int lengthType_function(const char *_tag_,int _type_,const char *limit) |
457 | { |
458 | if(_type_&XMLPARSE_TAG_START) |
459 | { |
460 | double l; |
461 | |
462 | XMLPARSE_ASSERT_FLOATING(_tag_,limit,l); |
463 | |
464 | loaded_profiles[nloaded_profiles-1]->length=metres_to_length(l); |
465 | } |
466 | |
467 | return(0); |
468 | } |
469 | |
470 | |
471 | /*++++++++++++++++++++++++++++++++++++++ |
472 | The function that is called when the restrictionsType XSD type is seen |
473 | |
474 | int restrictionsType_function Returns 0 if no error occured or something else otherwise. |
475 | |
476 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
477 | |
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 | ++++++++++++++++++++++++++++++++++++++*/ |
480 | |
481 | //static int restrictionsType_function(const char *_tag_,int _type_) |
482 | //{ |
483 | // return(0); |
484 | //} |
485 | |
486 | |
487 | /*++++++++++++++++++++++++++++++++++++++ |
488 | The function that is called when the profileType XSD type is seen |
489 | |
490 | int profileType_function Returns 0 if no error occured or something else otherwise. |
491 | |
492 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
493 | |
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. |
495 | |
496 | const char *name The contents of the 'name' attribute (or NULL if not defined). |
497 | |
498 | const char *transport The contents of the 'transport' attribute (or NULL if not defined). |
499 | ++++++++++++++++++++++++++++++++++++++*/ |
500 | |
501 | static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport) |
502 | { |
503 | if(_type_&XMLPARSE_TAG_START) |
504 | { |
505 | Transport transporttype; |
506 | int i; |
507 | |
508 | XMLPARSE_ASSERT_STRING(_tag_,name); |
509 | XMLPARSE_ASSERT_STRING(_tag_,transport); |
510 | |
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"); |
514 | |
515 | transporttype=TransportType(transport); |
516 | |
517 | if(transporttype==Transport_None) |
518 | XMLPARSE_INVALID(_tag_,transport); |
519 | |
520 | if((nloaded_profiles%16)==0) |
521 | loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*)); |
522 | |
523 | nloaded_profiles++; |
524 | |
525 | loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile)); |
526 | |
527 | loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name); |
528 | loaded_profiles[nloaded_profiles-1]->transport=transporttype; |
529 | } |
530 | |
531 | return(0); |
532 | } |
533 | |
534 | |
535 | /*++++++++++++++++++++++++++++++++++++++ |
536 | The function that is called when the RoutinoProfilesType XSD type is seen |
537 | |
538 | int RoutinoProfilesType_function Returns 0 if no error occured or something else otherwise. |
539 | |
540 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
541 | |
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 | ++++++++++++++++++++++++++++++++++++++*/ |
544 | |
545 | //static int RoutinoProfilesType_function(const char *_tag_,int _type_) |
546 | //{ |
547 | // return(0); |
548 | //} |
549 | |
550 | |
551 | /*++++++++++++++++++++++++++++++++++++++ |
552 | The function that is called when the XML declaration is seen |
553 | |
554 | int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. |
555 | |
556 | const char *_tag_ Set to the name of the element tag that triggered this function call. |
557 | |
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. |
559 | |
560 | const char *version The contents of the 'version' attribute (or NULL if not defined). |
561 | |
562 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). |
563 | ++++++++++++++++++++++++++++++++++++++*/ |
564 | |
565 | //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) |
566 | //{ |
567 | // return(0); |
568 | //} |
569 | |
570 | |
571 | /*++++++++++++++++++++++++++++++++++++++ |
572 | The XML profile parser. |
573 | |
574 | int ParseXMLProfiles Returns 0 if OK or something else in case of an error. |
575 | |
576 | const char *filename The name of the file to read. |
577 | ++++++++++++++++++++++++++++++++++++++*/ |
578 | |
579 | int ParseXMLProfiles(const char *filename) |
580 | { |
581 | int retval; |
582 | |
583 | if(!ExistsFile(filename)) |
584 | { |
585 | fprintf(stderr,"Error: Specified profiles file '%s' does not exist.\n",filename); |
586 | return(1); |
587 | } |
588 | |
589 | FILE *file=fopen(filename,"r"); |
590 | |
591 | if(!file) |
592 | { |
593 | fprintf(stderr,"Error: Cannot open profiles file '%s' for reading.\n",filename); |
594 | return(1); |
595 | } |
596 | |
597 | retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME); |
598 | |
599 | fclose(file); |
600 | |
601 | if(retval) |
602 | { |
603 | int i; |
604 | |
605 | for(i=0;i<nloaded_profiles;i++) |
606 | free(loaded_profiles[i]); |
607 | free(loaded_profiles); |
608 | |
609 | nloaded_profiles=0; |
610 | |
611 | return(1); |
612 | } |
613 | |
614 | return(0); |
615 | } |
616 | |
617 | |
618 | /*++++++++++++++++++++++++++++++++++++++ |
619 | Get the profile for a type of transport. |
620 | |
621 | Profile *GetProfile Returns a pointer to the profile. |
622 | |
623 | const char *name The name of the profile. |
624 | ++++++++++++++++++++++++++++++++++++++*/ |
625 | |
626 | Profile *GetProfile(const char *name) |
627 | { |
628 | int i; |
629 | |
630 | for(i=0;i<nloaded_profiles;i++) |
631 | if(!strcmp(loaded_profiles[i]->name,name)) |
632 | return(loaded_profiles[i]); |
633 | |
634 | return(NULL); |
635 | } |
636 | |
637 | |
638 | /*++++++++++++++++++++++++++++++++++++++ |
639 | Update a profile with highway preference scaling factor. |
640 | |
641 | int UpdateProfile Returns 1 in case of a problem. |
642 | |
643 | Profile *profile The profile to be updated. |
644 | |
645 | Ways *ways The set of ways to use. |
646 | ++++++++++++++++++++++++++++++++++++++*/ |
647 | |
648 | int UpdateProfile(Profile *profile,Ways *ways) |
649 | { |
650 | score_t hmax=0; |
651 | int i; |
652 | |
653 | /* Fix up the allowed transport types. */ |
654 | |
655 | profile->allow=ALLOWED(profile->transport); |
656 | |
657 | if(!(profile->allow & ways->allow)) |
658 | return(1); |
659 | |
660 | /* Normalise the highway preferences into the range 0 -> 1 */ |
661 | |
662 | for(i=1;i<Way_Count;i++) |
663 | { |
664 | if(profile->highway[i]<0) |
665 | profile->highway[i]=0; |
666 | |
667 | if(profile->highway[i]>hmax) |
668 | hmax=profile->highway[i]; |
669 | } |
670 | |
671 | if(hmax==0) |
672 | return(1); |
673 | |
674 | for(i=1;i<Way_Count;i++) |
675 | profile->highway[i]/=hmax; |
676 | |
677 | /* Normalise the property preferences into the range 0 -> 2 */ |
678 | |
679 | for(i=1;i<Property_Count;i++) |
680 | { |
681 | if(profile->props_yes[i]<0) |
682 | profile->props_yes[i]=0; |
683 | |
684 | if(profile->props_yes[i]>100) |
685 | profile->props_yes[i]=100; |
686 | |
687 | profile->props_yes[i]/=50; |
688 | profile->props_no [i] =2-profile->props_yes[i]; |
689 | } |
690 | |
691 | /* Find the fastest preferred speed */ |
692 | |
693 | profile->max_speed=0; |
694 | |
695 | for(i=1;i<Way_Count;i++) |
696 | if(profile->speed[i]>profile->max_speed) |
697 | profile->max_speed=profile->speed[i]; |
698 | |
699 | if(profile->max_speed==0) |
700 | return(1); |
701 | |
702 | /* Find the most preferred property combination */ |
703 | |
704 | profile->max_pref=1; /* since highway prefs were normalised to 1 */ |
705 | |
706 | for(i=1;i<Property_Count;i++) |
707 | if(ways->props & PROPERTIES(i)) |
708 | { |
709 | if(profile->props_yes[i]>profile->props_no[i]) |
710 | profile->max_pref*=profile->props_yes[i]; |
711 | else |
712 | profile->max_pref*=profile->props_no[i]; |
713 | } |
714 | |
715 | return(0); |
716 | } |
717 | |
718 | |
719 | /*++++++++++++++++++++++++++++++++++++++ |
720 | Print out a profile. |
721 | |
722 | const Profile *profile The profile to print. |
723 | ++++++++++++++++++++++++++++++++++++++*/ |
724 | |
725 | void PrintProfile(const Profile *profile) |
726 | { |
727 | unsigned int i; |
728 | |
729 | printf("Profile\n=======\n"); |
730 | |
731 | printf("\n"); |
732 | |
733 | printf("Transport: %s\n",TransportName(profile->transport)); |
734 | |
735 | printf("\n"); |
736 | |
737 | for(i=1;i<Way_Count;i++) |
738 | printf("Highway %-12s: %3d%%\n",HighwayName(i),(int)profile->highway[i]); |
739 | |
740 | printf("\n"); |
741 | |
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); |
745 | |
746 | printf("\n"); |
747 | |
748 | for(i=1;i<Property_Count;i++) |
749 | printf("Highway property %-12s: %3d%%\n",PropertyName(i),(int)profile->props_yes[i]); |
750 | |
751 | printf("\n"); |
752 | |
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)); |
758 | } |
759 | |
760 | |
761 | /*++++++++++++++++++++++++++++++++++++++ |
762 | Print out the profiles as XML for use as program input. |
763 | ++++++++++++++++++++++++++++++++++++++*/ |
764 | |
765 | void PrintProfilesXML(void) |
766 | { |
767 | unsigned int i,j; |
768 | char *padding=" "; |
769 | |
770 | printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); |
771 | printf("\n"); |
772 | |
773 | printf("<routino-profiles xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"routino-profiles.xsd\">\n"); |
774 | printf("\n"); |
775 | |
776 | for(j=0;j<nloaded_profiles;j++) |
777 | { |
778 | printf(" <profile name=\"%s\" transport=\"%s\">\n",loaded_profiles[j]->name,TransportName(loaded_profiles[j]->transport)); |
779 | |
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"); |
784 | |
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"); |
789 | |
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"); |
794 | |
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"); |
802 | |
803 | printf(" </profile>\n"); |
804 | printf("\n"); |
805 | } |
806 | |
807 | printf("</routino-profiles>\n"); |
808 | } |
809 | |
810 | |
811 | /*++++++++++++++++++++++++++++++++++++++ |
812 | Print out the profiles as JavaScript Object Notation for use in a web form. |
813 | ++++++++++++++++++++++++++++++++++++++*/ |
814 | |
815 | void PrintProfilesJSON(void) |
816 | { |
817 | unsigned int i,j; |
818 | |
819 | printf("var routino={ // contains all default Routino options (generated using \"--help-profile-json\").\n"); |
820 | printf("\n"); |
821 | |
822 | printf(" // Default transport type\n"); |
823 | printf(" transport: 'motorcar',\n"); |
824 | printf("\n"); |
825 | |
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); |
830 | printf("},\n"); |
831 | printf("\n"); |
832 | |
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); |
837 | printf("},\n"); |
838 | printf("\n"); |
839 | |
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); |
844 | printf("},\n"); |
845 | printf("\n"); |
846 | |
847 | printf(" // Restriction types\n"); |
848 | printf(" restrictions: {oneway: 1, weight: 2, height: 3, width: 4, length: 5},\n"); |
849 | printf("\n"); |
850 | |
851 | printf(" // Allowed highways\n"); |
852 | printf(" profile_highway: {\n"); |
853 | for(i=1;i<Way_Count;i++) |
854 | { |
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)?"":","); |
859 | } |
860 | printf(" },\n"); |
861 | printf("\n"); |
862 | |
863 | printf(" // Speed limits\n"); |
864 | printf(" profile_speed: {\n"); |
865 | for(i=1;i<Way_Count;i++) |
866 | { |
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)?"":","); |
871 | } |
872 | printf(" },\n"); |
873 | printf("\n"); |
874 | |
875 | printf(" // Highway properties\n"); |
876 | printf(" profile_property: {\n"); |
877 | for(i=1;i<Property_Count;i++) |
878 | { |
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)?"":","); |
883 | } |
884 | printf(" },\n"); |
885 | printf("\n"); |
886 | |
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); |
892 | printf("},\n"); |
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)); |
896 | printf("},\n"); |
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)); |
900 | printf("},\n"); |
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)); |
904 | printf("},\n"); |
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)); |
908 | printf("}\n"); |
909 | printf(" }\n"); |
910 | printf("\n"); |
911 | |
912 | printf("}; // end of routino variable\n"); |
913 | } |
914 | |
915 | |
916 | /*++++++++++++++++++++++++++++++++++++++ |
917 | Print out the profiles as Perl for use in a web CGI. |
918 | ++++++++++++++++++++++++++++++++++++++*/ |
919 | |
920 | void PrintProfilesPerl(void) |
921 | { |
922 | unsigned int i,j; |
923 | |
924 | printf("$routino={ # contains all default Routino options (generated using \"--help-profile-perl\").\n"); |
925 | printf("\n"); |
926 | |
927 | printf(" # Default transport type\n"); |
928 | printf(" transport => 'motorcar',\n"); |
929 | printf("\n"); |
930 | |
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); |
935 | printf("},\n"); |
936 | printf("\n"); |
937 | |
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); |
942 | printf("},\n"); |
943 | printf("\n"); |
944 | |
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); |
949 | printf("},\n"); |
950 | printf("\n"); |
951 | |
952 | printf(" # Restriction types\n"); |
953 | printf(" restrictions => {oneway => 1, weight => 2, height => 3, width => 4, length => 5},\n"); |
954 | printf("\n"); |
955 | |
956 | printf(" # Allowed highways\n"); |
957 | printf(" profile_highway => {\n"); |
958 | for(i=1;i<Way_Count;i++) |
959 | { |
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)?"":","); |
964 | } |
965 | printf(" },\n"); |
966 | printf("\n"); |
967 | |
968 | printf(" # Speed limits\n"); |
969 | printf(" profile_speed => {\n"); |
970 | for(i=1;i<Way_Count;i++) |
971 | { |
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)?"":","); |
976 | } |
977 | printf(" },\n"); |
978 | printf("\n"); |
979 | |
980 | printf(" # Highway properties\n"); |
981 | printf(" profile_property => {\n"); |
982 | for(i=1;i<Property_Count;i++) |
983 | { |
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)?"":","); |
988 | } |
989 | printf(" },\n"); |
990 | printf("\n"); |
991 | |
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); |
997 | printf("},\n"); |
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)); |
1001 | printf("},\n"); |
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)); |
1005 | printf("},\n"); |
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)); |
1009 | printf("},\n"); |
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)); |
1013 | printf("}\n"); |
1014 | printf(" },\n"); |
1015 | printf("\n"); |
1016 | |
1017 | printf("}; # end of routino variable\n"); |
1018 | } |
Properties
Name | Value |
---|---|
cvs:description | Definition of built-in profiles and other functions. |