Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/router.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1549 - (show annotations) (download) (as text)
Mon Apr 14 17:44:35 2014 UTC (10 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 27017 byte(s)
Check the number of waypoints after considering the --help and --help-profile
options.

1 /***************************************
2 OSM router.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2014 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27
28 #include "types.h"
29 #include "nodes.h"
30 #include "segments.h"
31 #include "ways.h"
32 #include "relations.h"
33
34 #include "files.h"
35 #include "logging.h"
36 #include "functions.h"
37 #include "fakes.h"
38 #include "translations.h"
39 #include "profiles.h"
40
41
42 /*+ To help when debugging +*/
43 #define DEBUG 0
44
45 /*+ The maximum distance from the specified point to search for a node or segment (in km). +*/
46 #define MAXSEARCH 1
47
48
49 /* Global variables */
50
51 /*+ The option not to print any progress information. +*/
52 int option_quiet=0;
53
54 /*+ The options to select the format of the output. +*/
55 int option_html=0,option_gpx_track=0,option_gpx_route=0,option_text=0,option_text_all=0,option_none=0,option_stdout=0;
56
57 /*+ The option to calculate the quickest route insted of the shortest. +*/
58 int option_quickest=0;
59
60
61 /* Local functions */
62
63 static void print_usage(int detail,const char *argerr,const char *err);
64 static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node);
65
66
67 /*++++++++++++++++++++++++++++++++++++++
68 The main program for the router.
69 ++++++++++++++++++++++++++++++++++++++*/
70
71 int main(int argc,char** argv)
72 {
73 Nodes *OSMNodes;
74 Segments *OSMSegments;
75 Ways *OSMWays;
76 Relations *OSMRelations;
77 Results *results[NWAYPOINTS+1]={NULL};
78 int point_used[NWAYPOINTS+1]={0};
79 double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
80 double heading=-999;
81 int help_profile=0,help_profile_xml=0,help_profile_json=0,help_profile_pl=0;
82 char *dirname=NULL,*prefix=NULL;
83 char *profiles=NULL,*profilename=NULL;
84 char *translations=NULL,*language=NULL;
85 int exactnodes=0,reverse=0,loop=0;
86 Transport transport=Transport_None;
87 Profile *profile=NULL;
88 index_t start_node,finish_node=NO_NODE,first_node=NO_NODE;
89 index_t join_segment=NO_SEGMENT;
90 int arg,nresults=0;
91 waypoint_t start_waypoint,finish_waypoint=NO_WAYPOINT;
92 waypoint_t first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint;
93
94 /* Parse the command line arguments */
95
96 if(argc<2)
97 print_usage(0,NULL,NULL);
98
99 /* Get the non-routing, general program options */
100
101 for(arg=1;arg<argc;arg++)
102 {
103 if(!strcmp(argv[arg],"--help"))
104 print_usage(1,NULL,NULL);
105 else if(!strcmp(argv[arg],"--help-profile"))
106 help_profile=1;
107 else if(!strcmp(argv[arg],"--help-profile-xml"))
108 help_profile_xml=1;
109 else if(!strcmp(argv[arg],"--help-profile-json"))
110 help_profile_json=1;
111 else if(!strcmp(argv[arg],"--help-profile-perl"))
112 help_profile_pl=1;
113 else if(!strncmp(argv[arg],"--dir=",6))
114 dirname=&argv[arg][6];
115 else if(!strncmp(argv[arg],"--prefix=",9))
116 prefix=&argv[arg][9];
117 else if(!strncmp(argv[arg],"--profiles=",11))
118 profiles=&argv[arg][11];
119 else if(!strncmp(argv[arg],"--translations=",15))
120 translations=&argv[arg][15];
121 else if(!strcmp(argv[arg],"--exact-nodes-only"))
122 exactnodes=1;
123 else if(!strcmp(argv[arg],"--reverse"))
124 reverse=1;
125 else if(!strcmp(argv[arg],"--loop"))
126 loop=1;
127 else if(!strcmp(argv[arg],"--quiet"))
128 option_quiet=1;
129 else if(!strcmp(argv[arg],"--loggable"))
130 option_loggable=1;
131 else if(!strcmp(argv[arg],"--output-html"))
132 option_html=1;
133 else if(!strcmp(argv[arg],"--output-gpx-track"))
134 option_gpx_track=1;
135 else if(!strcmp(argv[arg],"--output-gpx-route"))
136 option_gpx_route=1;
137 else if(!strcmp(argv[arg],"--output-text"))
138 option_text=1;
139 else if(!strcmp(argv[arg],"--output-text-all"))
140 option_text_all=1;
141 else if(!strcmp(argv[arg],"--output-none"))
142 option_none=1;
143 else if(!strcmp(argv[arg],"--output-stdout"))
144 { option_stdout=1; option_quiet=1; }
145 else if(!strncmp(argv[arg],"--profile=",10))
146 profilename=&argv[arg][10];
147 else if(!strncmp(argv[arg],"--language=",11))
148 language=&argv[arg][11];
149 else if(!strncmp(argv[arg],"--transport=",12))
150 {
151 transport=TransportType(&argv[arg][12]);
152
153 if(transport==Transport_None)
154 print_usage(0,argv[arg],NULL);
155 }
156 else
157 continue;
158
159 argv[arg]=NULL;
160 }
161
162 if(option_stdout && (option_html+option_gpx_track+option_gpx_route+option_text+option_text_all)!=1)
163 {
164 fprintf(stderr,"Error: The '--output-stdout' option requires exactly one other output option (but not '--output-none').\n");
165 exit(EXIT_FAILURE);
166 }
167
168 /* Load in the profiles */
169
170 if(transport==Transport_None)
171 transport=Transport_Motorcar;
172
173 if(profiles)
174 {
175 if(!ExistsFile(profiles))
176 {
177 fprintf(stderr,"Error: The '--profiles' option specifies a file that does not exist.\n");
178 exit(EXIT_FAILURE);
179 }
180 }
181 else
182 {
183 if(ExistsFile(FileName(dirname,prefix,"profiles.xml")))
184 profiles=FileName(dirname,prefix,"profiles.xml");
185 else if(ExistsFile(FileName(DATADIR,NULL,"profiles.xml")))
186 profiles=FileName(DATADIR,NULL,"profiles.xml");
187 else
188 {
189 fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
190 exit(EXIT_FAILURE);
191 }
192 }
193
194 if(ParseXMLProfiles(profiles))
195 {
196 fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
197 exit(EXIT_FAILURE);
198 }
199
200 /* Choose the selected profile. */
201
202 if(profilename)
203 {
204 profile=GetProfile(profilename);
205
206 if(!profile)
207 {
208 fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles);
209 exit(EXIT_FAILURE);
210 }
211 }
212 else
213 profile=GetProfile(TransportName(transport));
214
215 if(!profile)
216 {
217 profile=(Profile*)calloc(1,sizeof(Profile));
218 profile->transport=transport;
219 }
220
221 /* Parse the other command line arguments */
222
223 for(arg=1;arg<argc;arg++)
224 {
225 if(!argv[arg])
226 continue;
227 else if(!strcmp(argv[arg],"--shortest"))
228 option_quickest=0;
229 else if(!strcmp(argv[arg],"--quickest"))
230 option_quickest=1;
231 else if(!strncmp(argv[arg],"--lon",5) && isdigit(argv[arg][5]))
232 {
233 int point;
234 char *p=&argv[arg][6];
235
236 while(isdigit(*p)) p++;
237 if(*p++!='=')
238 print_usage(0,argv[arg],NULL);
239
240 point=atoi(&argv[arg][5]);
241 if(point>NWAYPOINTS || point_used[point]&1)
242 print_usage(0,argv[arg],NULL);
243
244 point_lon[point]=degrees_to_radians(atof(p));
245 point_used[point]+=1;
246
247 if(point<first_waypoint)
248 first_waypoint=point;
249 if(point>last_waypoint)
250 last_waypoint=point;
251 }
252 else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5]))
253 {
254 int point;
255 char *p=&argv[arg][6];
256
257 while(isdigit(*p)) p++;
258 if(*p++!='=')
259 print_usage(0,argv[arg],NULL);
260
261 point=atoi(&argv[arg][5]);
262 if(point>NWAYPOINTS || point_used[point]&2)
263 print_usage(0,argv[arg],NULL);
264
265 point_lat[point]=degrees_to_radians(atof(p));
266 point_used[point]+=2;
267
268 if(point<first_waypoint)
269 first_waypoint=point;
270 if(point>last_waypoint)
271 last_waypoint=point;
272 }
273 else if(!strncmp(argv[arg],"--heading=",10))
274 {
275 double h=atof(&argv[arg][10]);
276
277 if(h>=-360 && h<=360)
278 {
279 heading=h;
280
281 if(heading<0) heading+=360;
282 }
283 }
284 else if(!strncmp(argv[arg],"--transport=",12))
285 ; /* Done this already */
286 else if(!strncmp(argv[arg],"--highway-",10))
287 {
288 Highway highway;
289 char *equal=strchr(argv[arg],'=');
290 char *string;
291
292 if(!equal)
293 print_usage(0,argv[arg],NULL);
294
295 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10);
296 string[equal-argv[arg]-10]=0;
297
298 highway=HighwayType(string);
299
300 if(highway==Highway_None)
301 print_usage(0,argv[arg],NULL);
302
303 profile->highway[highway]=atof(equal+1);
304
305 free(string);
306 }
307 else if(!strncmp(argv[arg],"--speed-",8))
308 {
309 Highway highway;
310 char *equal=strchr(argv[arg],'=');
311 char *string;
312
313 if(!equal)
314 print_usage(0,argv[arg],NULL);
315
316 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8);
317 string[equal-argv[arg]-8]=0;
318
319 highway=HighwayType(string);
320
321 if(highway==Highway_None)
322 print_usage(0,argv[arg],NULL);
323
324 profile->speed[highway]=kph_to_speed(atof(equal+1));
325
326 free(string);
327 }
328 else if(!strncmp(argv[arg],"--property-",11))
329 {
330 Property property;
331 char *equal=strchr(argv[arg],'=');
332 char *string;
333
334 if(!equal)
335 print_usage(0,argv[arg],NULL);
336
337 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+11);
338 string[equal-argv[arg]-11]=0;
339
340 property=PropertyType(string);
341
342 if(property==Property_None)
343 print_usage(0,argv[arg],NULL);
344
345 profile->props_yes[property]=atof(equal+1);
346
347 free(string);
348 }
349 else if(!strncmp(argv[arg],"--oneway=",9))
350 profile->oneway=!!atoi(&argv[arg][9]);
351 else if(!strncmp(argv[arg],"--turns=",8))
352 profile->turns=!!atoi(&argv[arg][8]);
353 else if(!strncmp(argv[arg],"--weight=",9))
354 profile->weight=tonnes_to_weight(atof(&argv[arg][9]));
355 else if(!strncmp(argv[arg],"--height=",9))
356 profile->height=metres_to_height(atof(&argv[arg][9]));
357 else if(!strncmp(argv[arg],"--width=",8))
358 profile->width=metres_to_width(atof(&argv[arg][8]));
359 else if(!strncmp(argv[arg],"--length=",9))
360 profile->length=metres_to_length(atof(&argv[arg][9]));
361 else
362 print_usage(0,argv[arg],NULL);
363 }
364
365 /* Print one of the profiles if requested */
366
367 if(help_profile)
368 {
369 PrintProfile(profile);
370
371 return(0);
372 }
373 else if(help_profile_xml)
374 {
375 PrintProfilesXML();
376
377 return(0);
378 }
379 else if(help_profile_json)
380 {
381 PrintProfilesJSON();
382
383 return(0);
384 }
385 else if(help_profile_pl)
386 {
387 PrintProfilesPerl();
388
389 return(0);
390 }
391
392 /* Check the waypoints are valid */
393
394 for(waypoint=1;waypoint<=NWAYPOINTS;waypoint++)
395 if(point_used[waypoint]==1 || point_used[waypoint]==2)
396 print_usage(0,NULL,"All waypoints must have latitude and longitude.");
397
398 if(first_waypoint>=last_waypoint)
399 print_usage(0,NULL,"At least two waypoints must be specified.");
400
401 /* Load in the translations */
402
403 if(option_html==0 && option_gpx_track==0 && option_gpx_route==0 && option_text==0 && option_text_all==0 && option_none==0)
404 option_html=option_gpx_track=option_gpx_route=option_text=option_text_all=1;
405
406 if(option_html || option_gpx_route || option_gpx_track)
407 {
408 if(translations)
409 {
410 if(!ExistsFile(translations))
411 {
412 fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n");
413 exit(EXIT_FAILURE);
414 }
415 }
416 else
417 {
418 if(ExistsFile(FileName(dirname,prefix,"translations.xml")))
419 translations=FileName(dirname,prefix,"translations.xml");
420 else if(ExistsFile(FileName(DATADIR,NULL,"translations.xml")))
421 translations=FileName(DATADIR,NULL,"translations.xml");
422 else
423 {
424 fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n");
425 exit(EXIT_FAILURE);
426 }
427 }
428
429 if(ParseXMLTranslations(translations,language))
430 {
431 fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations);
432 exit(EXIT_FAILURE);
433 }
434 }
435
436 /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
437
438 OSMNodes=LoadNodeList(FileName(dirname,prefix,"nodes.mem"));
439
440 OSMSegments=LoadSegmentList(FileName(dirname,prefix,"segments.mem"));
441
442 OSMWays=LoadWayList(FileName(dirname,prefix,"ways.mem"));
443
444 OSMRelations=LoadRelationList(FileName(dirname,prefix,"relations.mem"));
445
446 if(UpdateProfile(profile,OSMWays))
447 {
448 fprintf(stderr,"Error: Profile is invalid or not compatible with database.\n");
449 exit(EXIT_FAILURE);
450 }
451
452 /* Check for reverse direction */
453
454 if(reverse)
455 {
456 waypoint_t temp;
457
458 temp=first_waypoint;
459 first_waypoint=last_waypoint;
460 last_waypoint=temp;
461
462 last_waypoint--;
463
464 inc_dec_waypoint=-1;
465 }
466 else
467 {
468 last_waypoint++;
469
470 inc_dec_waypoint=1;
471 }
472
473 /* Loop through all pairs of waypoints */
474
475 for(waypoint=first_waypoint;waypoint!=last_waypoint;waypoint+=inc_dec_waypoint)
476 {
477 distance_t distmax=km_to_distance(MAXSEARCH);
478 distance_t distmin;
479 index_t segment=NO_SEGMENT;
480 index_t node1,node2;
481
482 if(point_used[waypoint]!=3)
483 continue;
484
485 /* Find the closest point */
486
487 start_node=finish_node;
488 start_waypoint=finish_waypoint;
489
490 if(exactnodes)
491 {
492 finish_node=FindClosestNode(OSMNodes,OSMSegments,OSMWays,point_lat[waypoint],point_lon[waypoint],distmax,profile,&distmin);
493 }
494 else
495 {
496 distance_t dist1,dist2;
497
498 segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[waypoint],point_lon[waypoint],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2);
499
500 if(segment!=NO_SEGMENT)
501 finish_node=CreateFakes(OSMNodes,OSMSegments,waypoint,LookupSegment(OSMSegments,segment,1),node1,node2,dist1,dist2);
502 else
503 finish_node=NO_NODE;
504 }
505
506 if(finish_node==NO_NODE)
507 {
508 fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",waypoint);
509 exit(EXIT_FAILURE);
510 }
511
512 finish_waypoint=waypoint;
513
514 if(!option_quiet)
515 {
516 double lat,lon;
517
518 if(IsFakeNode(finish_node))
519 GetFakeLatLong(finish_node,&lat,&lon);
520 else
521 GetLatLong(OSMNodes,finish_node,NULL,&lat,&lon);
522
523 if(IsFakeNode(finish_node))
524 printf("Waypoint %d is segment %"Pindex_t" (node %"Pindex_t" -> %"Pindex_t"): %3.6f %4.6f = %2.3f km\n",waypoint,segment,node1,node2,
525 radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin));
526 else
527 printf("Waypoint %d is node %"Pindex_t": %3.6f %4.6f = %2.3f km\n",waypoint,finish_node,
528 radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin));
529 }
530
531 /* Check the nodes */
532
533 if(start_node==NO_NODE)
534 continue;
535
536 if(start_node==finish_node)
537 continue;
538
539 if(first_node==NO_NODE)
540 first_node=start_node;
541
542 if(heading!=-999 && join_segment==NO_SEGMENT)
543 join_segment=FindClosestSegmentHeading(OSMNodes,OSMSegments,OSMWays,start_node,heading,profile);
544
545 /* Calculate the route */
546
547 results[nresults]=CalculateRoute(OSMNodes,OSMSegments,OSMWays,OSMRelations,profile,start_node,join_segment,finish_node);
548
549 results[nresults]->start_waypoint=start_waypoint;
550 results[nresults]->finish_waypoint=finish_waypoint;
551
552 join_segment=results[nresults]->last_segment;
553
554 nresults++;
555 }
556
557 /* Finish the loop */
558
559 if(loop && finish_node!=NO_NODE)
560 {
561 results[nresults]=CalculateRoute(OSMNodes,OSMSegments,OSMWays,OSMRelations,profile,finish_node,join_segment,first_node);
562
563 results[nresults]->start_waypoint=last_waypoint;
564 results[nresults]->finish_waypoint=first_waypoint;
565
566 nresults++;
567 }
568
569 if(!option_quiet)
570 {
571 printf("Routed OK\n");
572 fflush(stdout);
573 }
574
575 /* Print out the combined route */
576
577 if(!option_none)
578 PrintRoute(results,nresults,OSMNodes,OSMSegments,OSMWays,profile);
579
580 /* Destroy the remaining results lists and data structures */
581
582 #if 0
583
584 for(waypoint=0;waypoint<=nresults;waypoint++)
585 FreeResultsList(results[waypoint]);
586
587 DestroyNodeList(OSMNodes);
588 DestroySegmentList(OSMSegments);
589 DestroyWayList(OSMWays);
590 DestroyRelationList(OSMRelations);
591
592 #endif
593
594 return(0);
595 }
596
597
598 /*++++++++++++++++++++++++++++++++++++++
599 Find a complete route from a specified node to another node.
600
601 Results *CalculateRoute Returns a set of results.
602
603 Nodes *nodes The set of nodes to use.
604
605 Segments *segments The set of segments to use.
606
607 Ways *ways The set of ways to use.
608
609 Relations *relations The set of relations to use.
610
611 Profile *profile The profile containing the transport type, speeds and allowed highways.
612
613 index_t start_node The start node.
614
615 index_t prev_segment The previous segment before the start node.
616
617 index_t finish_node The finish node.
618 ++++++++++++++++++++++++++++++++++++++*/
619
620 static Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node)
621 {
622 Results *begin,*end,*complete=NULL;
623
624 /* Calculate the beginning of the route */
625
626 begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
627
628 if(begin)
629 {
630 /* Check if the end of the route was reached */
631
632 if(begin->finish_node!=NO_NODE)
633 complete=ExtendStartRoutes(nodes,segments,ways,relations,profile,begin,finish_node);
634 }
635 else
636 {
637 if(prev_segment!=NO_SEGMENT)
638 {
639 /* Try again but allow a U-turn at the start waypoint -
640 this solves the problem of facing a dead-end that contains no super-nodes. */
641
642 prev_segment=NO_SEGMENT;
643
644 begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node);
645 }
646
647 if(begin)
648 {
649 /* Check if the end of the route was reached */
650
651 if(begin->finish_node!=NO_NODE)
652 complete=ExtendStartRoutes(nodes,segments,ways,relations,profile,begin,finish_node);
653 }
654 else
655 {
656 fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n");
657 exit(EXIT_FAILURE);
658 }
659 }
660
661 /* Calculate the rest of the route */
662
663 if(!complete)
664 {
665 Results *middle;
666
667 /* Calculate the end of the route */
668
669 end=FindFinishRoutes(nodes,segments,ways,relations,profile,finish_node);
670
671 if(!end)
672 {
673 fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n");
674 exit(EXIT_FAILURE);
675 }
676
677 /* Calculate the middle of the route */
678
679 middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
680
681 if(!middle && prev_segment!=NO_SEGMENT)
682 {
683 /* Try again but allow a U-turn at the start waypoint -
684 this solves the problem of facing a dead-end that contains some super-nodes. */
685
686 FreeResultsList(begin);
687
688 begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,NO_SEGMENT,finish_node);
689
690 if(begin)
691 middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end);
692 }
693
694 FreeResultsList(end);
695
696 if(!middle)
697 {
698 fprintf(stderr,"Error: Cannot find super-route compatible with profile.\n");
699 exit(EXIT_FAILURE);
700 }
701
702 complete=CombineRoutes(nodes,segments,ways,relations,profile,begin,middle);
703
704 if(!complete)
705 {
706 fprintf(stderr,"Error: Cannot create combined route following super-route.\n");
707 exit(EXIT_FAILURE);
708 }
709
710 FreeResultsList(begin);
711
712 FreeResultsList(middle);
713 }
714
715 #if DEBUG
716 Result *r=FindResult(complete,complete->start_node,complete->prev_segment);
717
718 printf("The final route is:\n");
719
720 while(r)
721 {
722 printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
723
724 r=r->next;
725 }
726 #endif
727
728 return(complete);
729 }
730
731
732 /*++++++++++++++++++++++++++++++++++++++
733 Print out the usage information.
734
735 int detail The level of detail to use - 0 = low, 1 = high.
736
737 const char *argerr The argument that gave the error (if there is one).
738
739 const char *err Other error message (if there is one).
740 ++++++++++++++++++++++++++++++++++++++*/
741
742 static void print_usage(int detail,const char *argerr,const char *err)
743 {
744 fprintf(stderr,
745 "Usage: router [--help | --help-profile | --help-profile-xml |\n"
746 " --help-profile-json | --help-profile-perl ]\n"
747 " [--dir=<dirname>] [--prefix=<name>]\n"
748 " [--profiles=<filename>] [--translations=<filename>]\n"
749 " [--exact-nodes-only]\n"
750 " [--loggable | --quiet]\n"
751 " [--language=<lang>]\n"
752 " [--output-html]\n"
753 " [--output-gpx-track] [--output-gpx-route]\n"
754 " [--output-text] [--output-text-all]\n"
755 " [--output-none] [--output-stdout]\n"
756 " [--profile=<name>]\n"
757 " [--transport=<transport>]\n"
758 " [--shortest | --quickest]\n"
759 " --lon1=<longitude> --lat1=<latitude>\n"
760 " --lon2=<longitude> --lon2=<latitude>\n"
761 " [ ... --lon99=<longitude> --lon99=<latitude>]\n"
762 " [--reverse] [--loop]\n"
763 " [--highway-<highway>=<preference> ...]\n"
764 " [--speed-<highway>=<speed> ...]\n"
765 " [--property-<property>=<preference> ...]\n"
766 " [--oneway=(0|1)] [--turns=(0|1)]\n"
767 " [--weight=<weight>]\n"
768 " [--height=<height>] [--width=<width>] [--length=<length>]\n");
769
770 if(argerr)
771 fprintf(stderr,
772 "\n"
773 "Error with command line parameter: %s\n",argerr);
774
775 if(err)
776 fprintf(stderr,
777 "\n"
778 "Error: %s\n",err);
779
780 if(detail)
781 fprintf(stderr,
782 "\n"
783 "--help Prints this information.\n"
784 "--help-profile Prints the information about the selected profile.\n"
785 "--help-profile-xml Prints all loaded profiles in XML format.\n"
786 "--help-profile-json Prints all loaded profiles in JSON format.\n"
787 "--help-profile-perl Prints all loaded profiles in Perl format.\n"
788 "\n"
789 "--dir=<dirname> The directory containing the routing database.\n"
790 "--prefix=<name> The filename prefix for the routing database.\n"
791 "--profiles=<filename> The name of the XML file containing the profiles\n"
792 " (defaults to 'profiles.xml' with '--dir' and\n"
793 " '--prefix' options or the file installed in\n"
794 " '" DATADIR "').\n"
795 "--translations=<fname> The name of the XML file containing the translations\n"
796 " (defaults to 'translations.xml' with '--dir' and\n"
797 " '--prefix' options or the file installed in\n"
798 " '" DATADIR "').\n"
799 "\n"
800 "--exact-nodes-only Only route between nodes (don't find closest segment).\n"
801 "\n"
802 "--loggable Print progress messages suitable for logging to file.\n"
803 "--quiet Don't print any screen output when running.\n"
804 "\n"
805 "--language=<lang> Use the translations for specified language.\n"
806 "--output-html Write an HTML description of the route.\n"
807 "--output-gpx-track Write a GPX track file with all route points.\n"
808 "--output-gpx-route Write a GPX route file with interesting junctions.\n"
809 "--output-text Write a plain text file with interesting junctions.\n"
810 "--output-text-all Write a plain test file with all route points.\n"
811 "--output-none Don't write any output files or read any translations.\n"
812 " (If no output option is given then all are written.)\n"
813 "--output-stdout Write to stdout instead of a file (requires exactly\n"
814 " one output format option, implies '--quiet').\n"
815 "\n"
816 "--profile=<name> Select the loaded profile with this name.\n"
817 "--transport=<transport> Select the transport to use (selects the profile\n"
818 " named after the transport if '--profile' is not used.)\n"
819 "\n"
820 "--shortest Find the shortest route between the waypoints.\n"
821 "--quickest Find the quickest route between the waypoints.\n"
822 "\n"
823 "--lon<n>=<longitude> Specify the longitude of the n'th waypoint.\n"
824 "--lat<n>=<latitude> Specify the latitude of the n'th waypoint.\n"
825 "\n"
826 "--reverse Find a route between the waypoints in reverse order.\n"
827 "--loop Find a route that returns to the first waypoint.\n"
828 "\n"
829 "--heading=<bearing> Initial compass bearing at lowest numbered waypoint.\n"
830 "\n"
831 " Routing preference options\n"
832 "--highway-<highway>=<preference> * preference for highway type (%%).\n"
833 "--speed-<highway>=<speed> * speed for highway type (km/h).\n"
834 "--property-<property>=<preference> * preference for proprty type (%%).\n"
835 "--oneway=(0|1) * oneway restrictions are to be obeyed.\n"
836 "--turns=(0|1) * turn restrictions are to be obeyed.\n"
837 "--weight=<weight> * maximum weight limit (tonnes).\n"
838 "--height=<height> * maximum height limit (metres).\n"
839 "--width=<width> * maximum width limit (metres).\n"
840 "--length=<length> * maximum length limit (metres).\n"
841 "\n"
842 "<transport> defaults to motorcar but can be set to:\n"
843 "%s"
844 "\n"
845 "<highway> can be selected from:\n"
846 "%s"
847 "\n"
848 "<property> can be selected from:\n"
849 "%s",
850 TransportList(),HighwayList(),PropertyList());
851
852 exit(!detail);
853 }

Properties

Name Value
cvs:description Router.