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