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