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 431 - (show annotations) (download) (as text)
Mon Jun 28 17:56:26 2010 UTC (14 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 24590 byte(s)
Don't crash if start and finish are the same point.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/router.c,v 1.83 2010-06-28 17:56:26 amb Exp $
3
4 OSM router.
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 #include <ctype.h>
29
30 #include "types.h"
31 #include "functions.h"
32 #include "translations.h"
33 #include "profiles.h"
34 #include "nodes.h"
35 #include "segments.h"
36 #include "ways.h"
37
38
39 /*+ The number of waypoints allowed to be specified. +*/
40 #define NWAYPOINTS 99
41
42 /*+ The maximum distance from the specified point to search for a node or segment (in km). +*/
43 #define MAXSEARCH 1
44
45 /*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/
46 #define MINSEGMENT 0.005
47
48
49 /*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
50 static Segment fake_segments[2*NWAYPOINTS];
51
52 /*+ A set of fake node latitudes and longitudes. +*/
53 static double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
54
55 /*+ The option not to print any progress information. +*/
56 int option_quiet=0;
57
58 /*+ The options to select the format of the output. +*/
59 int option_html=0,option_gpx_track=0,option_gpx_route=0,option_text=0,option_text_all=0,option_none=0;
60
61 /*+ The option to calculate the quickest route insted of the shortest. +*/
62 int option_quickest=0;
63
64
65 /* Local functions */
66
67 static void print_usage(int detail);
68
69
70 /*++++++++++++++++++++++++++++++++++++++
71 The main program for the router.
72 ++++++++++++++++++++++++++++++++++++++*/
73
74 int main(int argc,char** argv)
75 {
76 Nodes *OSMNodes;
77 Segments *OSMSegments;
78 Ways *OSMWays;
79 Results *results[NWAYPOINTS+1]={NULL};
80 int point_used[NWAYPOINTS+1]={0};
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;
86 Transport transport=Transport_None;
87 Profile *profile=NULL;
88 index_t start=NO_NODE,finish=NO_NODE;
89 int arg,point;
90
91 /* Parse the command line arguments */
92
93 if(argc<2)
94 print_usage(0);
95
96 /* Get the non-routing, general program options */
97
98 for(arg=1;arg<argc;arg++)
99 {
100 if(!strcmp(argv[arg],"--help"))
101 print_usage(1);
102 else if(!strcmp(argv[arg],"--help-profile"))
103 help_profile=1;
104 else if(!strcmp(argv[arg],"--help-profile-xml"))
105 help_profile_xml=1;
106 else if(!strcmp(argv[arg],"--help-profile-json"))
107 help_profile_json=1;
108 else if(!strcmp(argv[arg],"--help-profile-perl"))
109 help_profile_pl=1;
110 else if(!strncmp(argv[arg],"--dir=",6))
111 dirname=&argv[arg][6];
112 else if(!strncmp(argv[arg],"--prefix=",9))
113 prefix=&argv[arg][9];
114 else if(!strncmp(argv[arg],"--profiles=",11))
115 profiles=&argv[arg][11];
116 else if(!strncmp(argv[arg],"--translations=",15))
117 translations=&argv[arg][15];
118 else if(!strcmp(argv[arg],"--exact-nodes-only"))
119 exactnodes=1;
120 else if(!strcmp(argv[arg],"--quiet"))
121 option_quiet=1;
122 else if(!strcmp(argv[arg],"--output-html"))
123 option_html=1;
124 else if(!strcmp(argv[arg],"--output-gpx-track"))
125 option_gpx_track=1;
126 else if(!strcmp(argv[arg],"--output-gpx-route"))
127 option_gpx_route=1;
128 else if(!strcmp(argv[arg],"--output-text"))
129 option_text=1;
130 else if(!strcmp(argv[arg],"--output-text-all"))
131 option_text_all=1;
132 else if(!strcmp(argv[arg],"--output-none"))
133 option_none=1;
134 else if(!strncmp(argv[arg],"--profile=",10))
135 profilename=&argv[arg][10];
136 else if(!strncmp(argv[arg],"--language=",11))
137 language=&argv[arg][11];
138 else if(!strncmp(argv[arg],"--transport=",12))
139 {
140 transport=TransportType(&argv[arg][12]);
141
142 if(transport==Transport_None)
143 print_usage(0);
144 }
145 else
146 continue;
147
148 argv[arg]=NULL;
149 }
150
151 /* Load in the profiles */
152
153 if(transport==Transport_None)
154 transport=Transport_Motorcar;
155
156 if(profiles)
157 {
158 if(!ExistsFile(profiles))
159 {
160 fprintf(stderr,"Error: The '--profiles' option specifies a file that does not exist.\n");
161 return(1);
162 }
163 }
164 else
165 {
166 if(ExistsFile(FileName(dirname,prefix,"profiles.xml")))
167 profiles=FileName(dirname,prefix,"profiles.xml");
168 else
169 {
170 fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
171 return(1);
172 }
173 }
174
175 if(profiles && ParseXMLProfiles(profiles))
176 {
177 fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
178 return(1);
179 }
180
181 if(profilename)
182 {
183 profile=GetProfile(profilename);
184
185 if(!profile)
186 {
187 fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles);
188 return(1);
189 }
190 }
191 else
192 profile=GetProfile(TransportName(transport));
193
194 if(!profile)
195 {
196 profile=(Profile*)calloc(1,sizeof(Profile));
197 profile->transport=transport;
198 }
199
200 /* Parse the other command line arguments */
201
202 for(arg=1;arg<argc;arg++)
203 {
204 if(!argv[arg])
205 continue;
206 else if(!strcmp(argv[arg],"--shortest"))
207 option_quickest=0;
208 else if(!strcmp(argv[arg],"--quickest"))
209 option_quickest=1;
210 else if(isdigit(argv[arg][0]) ||
211 ((argv[arg][0]=='-' || argv[arg][0]=='+') && isdigit(argv[arg][1])))
212 {
213 for(point=1;point<=NWAYPOINTS;point++)
214 if(point_used[point]!=3)
215 {
216 if(point_used[point]==0)
217 {
218 point_lon[point]=degrees_to_radians(atof(argv[arg]));
219 point_used[point]=1;
220 }
221 else /* if(point_used[point]==1) */
222 {
223 point_lat[point]=degrees_to_radians(atof(argv[arg]));
224 point_used[point]=3;
225 }
226 break;
227 }
228 }
229 else if(!strncmp(argv[arg],"--lon",5) && isdigit(argv[arg][5]))
230 {
231 char *p=&argv[arg][6];
232 while(isdigit(*p)) p++;
233 if(*p++!='=')
234 print_usage(0);
235
236 point=atoi(&argv[arg][5]);
237 if(point>NWAYPOINTS || point_used[point]&1)
238 print_usage(0);
239
240 point_lon[point]=degrees_to_radians(atof(p));
241 point_used[point]+=1;
242 }
243 else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5]))
244 {
245 char *p=&argv[arg][6];
246 while(isdigit(*p)) p++;
247 if(*p++!='=')
248 print_usage(0);
249
250 point=atoi(&argv[arg][5]);
251 if(point>NWAYPOINTS || point_used[point]&2)
252 print_usage(0);
253
254 point_lat[point]=degrees_to_radians(atof(p));
255 point_used[point]+=2;
256 }
257 else if(!strncmp(argv[arg],"--transport=",12))
258 ; /* Done this already */
259 else if(!strncmp(argv[arg],"--highway-",10))
260 {
261 Highway highway;
262 char *equal=strchr(argv[arg],'=');
263 char *string;
264
265 if(!equal)
266 print_usage(0);
267
268 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10);
269 string[equal-argv[arg]-10]=0;
270
271 highway=HighwayType(string);
272
273 if(highway==Way_Count)
274 print_usage(0);
275
276 profile->highway[highway]=atof(equal+1);
277
278 free(string);
279 }
280 else if(!strncmp(argv[arg],"--speed-",8))
281 {
282 Highway highway;
283 char *equal=strchr(argv[arg],'=');
284 char *string;
285
286 if(!equal)
287 print_usage(0);
288
289 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8);
290 string[equal-argv[arg]-8]=0;
291
292 highway=HighwayType(string);
293
294 if(highway==Way_Count)
295 print_usage(0);
296
297 profile->speed[highway]=kph_to_speed(atof(equal+1));
298
299 free(string);
300 }
301 else if(!strncmp(argv[arg],"--property-",11))
302 {
303 Property property;
304 char *equal=strchr(argv[arg],'=');
305 char *string;
306
307 if(!equal)
308 print_usage(0);
309
310 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+11);
311 string[equal-argv[arg]-11]=0;
312
313 property=PropertyType(string);
314
315 if(property==Way_Count)
316 print_usage(0);
317
318 profile->props_yes[property]=atof(equal+1);
319
320 free(string);
321 }
322 else if(!strncmp(argv[arg],"--oneway=",9))
323 profile->oneway=!!atoi(&argv[arg][9]);
324 else if(!strncmp(argv[arg],"--weight=",9))
325 profile->weight=tonnes_to_weight(atof(&argv[arg][9]));
326 else if(!strncmp(argv[arg],"--height=",9))
327 profile->height=metres_to_height(atof(&argv[arg][9]));
328 else if(!strncmp(argv[arg],"--width=",8))
329 profile->width=metres_to_width(atof(&argv[arg][8]));
330 else if(!strncmp(argv[arg],"--length=",9))
331 profile->length=metres_to_length(atof(&argv[arg][9]));
332 else
333 print_usage(0);
334 }
335
336 for(point=1;point<=NWAYPOINTS;point++)
337 if(point_used[point]==1 || point_used[point]==2)
338 print_usage(0);
339
340 if(help_profile)
341 {
342 PrintProfile(profile);
343
344 return(0);
345 }
346 else if(help_profile_xml)
347 {
348 PrintProfilesXML();
349
350 return(0);
351 }
352 else if(help_profile_json)
353 {
354 PrintProfilesJSON();
355
356 return(0);
357 }
358 else if(help_profile_pl)
359 {
360 PrintProfilesPerl();
361
362 return(0);
363 }
364
365 /* Load in the translations */
366
367 if(option_html==0 && option_gpx_track==0 && option_gpx_route==0 && option_text==0 && option_text_all==0 && option_none==0)
368 option_html=option_gpx_track=option_gpx_route=option_text=option_text_all=1;
369
370 if(option_html || option_gpx_route || option_gpx_track)
371 {
372 if(translations && ExistsFile(translations))
373 ;
374 else if(!translations && ExistsFile(FileName(dirname,prefix,"translations.xml")))
375 translations=FileName(dirname,prefix,"translations.xml");
376
377 if(!translations && language)
378 {
379 fprintf(stderr,"Error: Cannot use '--language' option without reading some translations.\n");
380 return(1);
381 }
382
383 if(translations && ParseXMLTranslations(translations,language))
384 {
385 fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations);
386 return(1);
387 }
388 }
389
390 /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
391
392 OSMNodes=LoadNodeList(FileName(dirname,prefix,"nodes.mem"));
393
394 OSMSegments=LoadSegmentList(FileName(dirname,prefix,"segments.mem"));
395
396 OSMWays=LoadWayList(FileName(dirname,prefix,"ways.mem"));
397
398 if(UpdateProfile(profile,OSMWays))
399 {
400 fprintf(stderr,"Error: Profile is invalid or not compatible with database.\n");
401 return(1);
402 }
403
404 /* Loop through all pairs of points */
405
406 for(point=1;point<=NWAYPOINTS;point++)
407 {
408 Results *begin,*end;
409 distance_t distmax=km_to_distance(MAXSEARCH);
410 distance_t distmin;
411 Segment *segment=NULL;
412 index_t node1,node2;
413
414 if(point_used[point]!=3)
415 continue;
416
417 /* Find the closest point */
418
419 start=finish;
420
421 if(exactnodes)
422 {
423 finish=FindClosestNode(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin);
424 }
425 else
426 {
427 distance_t dist1,dist2;
428
429 if((segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2)))
430 finish=CreateFakes(OSMNodes,point,segment,node1,node2,dist1,dist2);
431 else
432 finish=NO_NODE;
433 }
434
435 if(finish==NO_NODE)
436 {
437 fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",point);
438 return(1);
439 }
440
441 if(!option_quiet)
442 {
443 double lat,lon;
444
445 if(IsFakeNode(finish))
446 GetFakeLatLong(finish,&lat,&lon);
447 else
448 GetLatLong(OSMNodes,finish,&lat,&lon);
449
450 if(IsFakeNode(finish))
451 printf("Point %d is segment %d (node %d -> %d): %3.6f %4.6f = %2.3f km\n",point,IndexSegment(OSMSegments,segment),node1,node2,
452 radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin));
453 else
454 printf("Point %d is node %d: %3.6f %4.6f = %2.3f km\n",point,finish,
455 radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin));
456 }
457
458 if(start==NO_NODE)
459 continue;
460
461 if(start==finish)
462 continue;
463
464 /* Calculate the beginning of the route */
465
466 if(!IsFakeNode(start) && IsSuperNode(OSMNodes,start))
467 {
468 Result *result;
469
470 begin=NewResultsList(1);
471
472 begin->start=start;
473
474 result=InsertResult(begin,start);
475
476 ZeroResult(result);
477 }
478 else
479 {
480 begin=FindStartRoutes(OSMNodes,OSMSegments,OSMWays,start,profile);
481
482 if(!begin)
483 {
484 fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n");
485 return(1);
486 }
487 }
488
489 if(FindResult(begin,finish))
490 {
491 FixForwardRoute(begin,finish);
492
493 results[point]=begin;
494
495 if(!option_quiet)
496 {
497 printf("\rRouted: Super-Nodes Checked = %d\n",begin->number);
498 fflush(stdout);
499 }
500 }
501 else
502 {
503 Results *superresults;
504
505 /* Calculate the end of the route */
506
507 if(!IsFakeNode(finish) && IsSuperNode(OSMNodes,finish))
508 {
509 Result *result;
510
511 end=NewResultsList(1);
512
513 end->finish=finish;
514
515 result=InsertResult(end,finish);
516
517 ZeroResult(result);
518 }
519 else
520 {
521 end=FindFinishRoutes(OSMNodes,OSMSegments,OSMWays,finish,profile);
522
523 if(!end)
524 {
525 fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n");
526 return(1);
527 }
528 }
529
530 /* Calculate the middle of the route */
531
532 superresults=FindMiddleRoute(OSMNodes,OSMSegments,OSMWays,begin,end,profile);
533
534 FreeResultsList(begin);
535 FreeResultsList(end);
536
537 if(!superresults)
538 {
539 fprintf(stderr,"Error: Cannot find route compatible with profile.\n");
540 return(1);
541 }
542
543 results[point]=CombineRoutes(superresults,OSMNodes,OSMSegments,OSMWays,profile);
544
545 FreeResultsList(superresults);
546 }
547 }
548
549 /* Print out the combined route */
550
551 if(!option_none)
552 PrintRoute(results,NWAYPOINTS,OSMNodes,OSMSegments,OSMWays,profile);
553
554 return(0);
555 }
556
557
558 /*++++++++++++++++++++++++++++++++++++++
559 Create a pair of fake segments corresponding to the given segment split in two.
560
561 index_t CreateFakes Returns the fake node index (or a real one in special cases).
562
563 Nodes *nodes The set of nodes to use.
564
565 int point Which of the waypoints is this.
566
567 Segment *segment The segment to split.
568
569 index_t node1 The first node at the end of this segment.
570
571 index_t node2 The second node at the end of this segment.
572
573 distance_t dist1 The distance to the first node.
574
575 distance_t dist2 The distance to the second node.
576 ++++++++++++++++++++++++++++++++++++++*/
577
578 index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2)
579 {
580 index_t fakenode;
581 double lat1,lon1,lat2,lon2;
582
583 /* Check if we are actually close enough to an existing node */
584
585 if(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
586 return(node1);
587
588 if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
589 return(node2);
590
591 if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
592 {
593 if(dist1<dist2)
594 return(node1);
595 else
596 return(node2);
597 }
598
599 /* Create the fake node */
600
601 fakenode=point|NODE_SUPER;
602
603 GetLatLong(nodes,node1,&lat1,&lon1);
604 GetLatLong(nodes,node2,&lat2,&lon2);
605
606 if(lat1>3 && lat2<-3)
607 lat2+=2*M_PI;
608 else if(lat1<-3 && lat2>3)
609 lat1+=2*M_PI;
610
611 point_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2);
612 point_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2);
613
614 if(point_lat[point]>M_PI) point_lat[point]-=2*M_PI;
615
616 /* Create the first fake segment */
617
618 fake_segments[2*point-2]=*segment;
619
620 if(segment->node1==node1)
621 fake_segments[2*point-2].node1=fakenode;
622 else
623 fake_segments[2*point-2].node2=fakenode;
624
625 fake_segments[2*point-2].distance=DISTANCE(dist1)|DISTFLAG(segment->distance);
626
627 /* Create the second fake segment */
628
629 fake_segments[2*point-1]=*segment;
630
631 if(segment->node1==node2)
632 fake_segments[2*point-1].node1=fakenode;
633 else
634 fake_segments[2*point-1].node2=fakenode;
635
636 fake_segments[2*point-1].distance=DISTANCE(dist2)|DISTFLAG(segment->distance);
637
638 return(fakenode);
639 }
640
641
642 /*++++++++++++++++++++++++++++++++++++++
643 Lookup the latitude and longitude of a fake node.
644
645 index_t fakenode The node to lookup.
646
647 double *latitude Returns the latitude
648
649 double *longitude Returns the longitude.
650 ++++++++++++++++++++++++++++++++++++++*/
651
652 void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude)
653 {
654 index_t realnode=fakenode&(~NODE_SUPER);
655
656 *latitude =point_lat[realnode];
657 *longitude=point_lon[realnode];
658 }
659
660
661 /*++++++++++++++++++++++++++++++++++++++
662 Finds the first fake segment associated to a fake node.
663
664 Segment *FirstFakeSegment Returns the first fake segment.
665
666 index_t fakenode The node to lookup.
667 ++++++++++++++++++++++++++++++++++++++*/
668
669 Segment *FirstFakeSegment(index_t fakenode)
670 {
671 index_t realnode=fakenode&(~NODE_SUPER);
672
673 return(&fake_segments[2*realnode-2]);
674 }
675
676
677 /*++++++++++++++++++++++++++++++++++++++
678 Finds the next (there can only be two) fake segment associated to a fake node.
679
680 Segment *NextFakeSegment Returns the second fake segment.
681
682 Segment *segment The first fake segment.
683
684 index_t fakenode The node to lookup.
685 ++++++++++++++++++++++++++++++++++++++*/
686
687 Segment *NextFakeSegment(Segment *segment,index_t fakenode)
688 {
689 index_t realnode=fakenode&(~NODE_SUPER);
690
691 if(segment==&fake_segments[2*realnode-2])
692 return(&fake_segments[2*realnode-1]);
693 else
694 return(NULL);
695 }
696
697
698 /*++++++++++++++++++++++++++++++++++++++
699 Finds the next (there can only be two) fake segment associated to a fake node.
700
701 Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists.
702
703 index_t node The real node.
704
705 index_t fakenode The fake node to lookup.
706 ++++++++++++++++++++++++++++++++++++++*/
707
708 Segment *ExtraFakeSegment(index_t node,index_t fakenode)
709 {
710 index_t realnode=fakenode&(~NODE_SUPER);
711
712 if(fake_segments[2*realnode-2].node1==node || fake_segments[2*realnode-2].node2==node)
713 return(&fake_segments[2*realnode-2]);
714
715 if(fake_segments[2*realnode-1].node1==node || fake_segments[2*realnode-1].node2==node)
716 return(&fake_segments[2*realnode-1]);
717
718 return(NULL);
719 }
720
721
722 /*++++++++++++++++++++++++++++++++++++++
723 Print out the usage information.
724
725 int detail The level of detail to use - 0 = low, 1 = high.
726 ++++++++++++++++++++++++++++++++++++++*/
727
728 static void print_usage(int detail)
729 {
730 fprintf(stderr,
731 "Usage: router [--help | --help-profile | --help-profile-xml |\n"
732 " --help-profile-json | --help-profile-perl ]\n"
733 " [--dir=<dirname>] [--prefix=<name>]\n"
734 " [--profiles=<filename>] [--translations=<filename>]\n"
735 " [--exact-nodes-only]\n"
736 " [--quiet]\n"
737 " [--language=<lang>]\n"
738 " [--output-html]\n"
739 " [--output-gpx-track] [--output-gpx-route]\n"
740 " [--output-text] [--output-text-all]\n"
741 " [--output-none]\n"
742 " [--profile=<name>]\n"
743 " [--transport=<transport>]\n"
744 " [--shortest | --quickest]\n"
745 " --lon1=<longitude> --lat1=<latitude>\n"
746 " --lon2=<longitude> --lon2=<latitude>\n"
747 " [ ... --lon99=<longitude> --lon99=<latitude>]\n"
748 " [--highway-<highway>=<preference> ...]\n"
749 " [--speed-<highway>=<speed> ...]\n"
750 " [--property-<property>=<preference> ...]\n"
751 " [--oneway=(0|1)]\n"
752 " [--weight=<weight>]\n"
753 " [--height=<height>] [--width=<width>] [--length=<length>]\n");
754
755 if(detail)
756 fprintf(stderr,
757 "\n"
758 "--help Prints this information.\n"
759 "--help-profile Prints the information about the selected profile.\n"
760 "--help-profile-xml Prints all loaded profiles in XML format.\n"
761 "--help-profile-json Prints all loaded profiles in JSON format.\n"
762 "--help-profile-perl Prints all loaded profiles in Perl format.\n"
763 "\n"
764 "--dir=<dirname> The directory containing the routing database.\n"
765 "--prefix=<name> The filename prefix for the routing database.\n"
766 "--profiles=<filename> The name of the profiles (defaults to 'profiles.xml'\n"
767 " with '--dirname' and '--prefix' options).\n"
768 "--translations=<fname> The filename of the translations (defaults to\n"
769 " 'translations.xml' with '--dirname' and '--prefix').\n"
770 "\n"
771 "--exact-nodes-only Only route between nodes (don't find closest segment).\n"
772 "\n"
773 "--quiet Don't print any screen output when running.\n"
774 "--language=<lang> Use the translations for specified language.\n"
775 "--output-html Write an HTML description of the route.\n"
776 "--output-gpx-track Write a GPX track file with all route points.\n"
777 "--output-gpx-route Write a GPX route file with interesting junctions.\n"
778 "--output-text Write a plain text file with interesting junctions.\n"
779 "--output-text-all Write a plain test file with all route points.\n"
780 "--output-none Don't write any output files or read any translations.\n"
781 " (If no output option is given then all are written.)\n"
782 "\n"
783 "--profile=<name> Select the loaded profile with this name.\n"
784 "--transport=<transport> Select the transport to use (selects the profile\n"
785 " named after the transport if '--profile' is not used.)\n"
786 "\n"
787 "--shortest Find the shortest route between the waypoints.\n"
788 "--quickest Find the quickest route between the waypoints.\n"
789 "\n"
790 "--lon<n>=<longitude> Specify the longitude of the n'th waypoint.\n"
791 "--lat<n>=<latitude> Specify the latitude of the n'th waypoint.\n"
792 "\n"
793 " Routing preference options\n"
794 "--highway-<highway>=<preference> * preference for highway type (%%).\n"
795 "--speed-<highway>=<speed> * speed for highway type (km/h).\n"
796 "--property-<property>=<preference> * preference for proprty type (%%).\n"
797 "--oneway=(0|1) * oneway streets are to be obeyed.\n"
798 "--weight=<weight> * maximum weight limit (tonnes).\n"
799 "--height=<height> * maximum height limit (metres).\n"
800 "--width=<width> * maximum width limit (metres).\n"
801 "--length=<length> * maximum length limit (metres).\n"
802 "\n"
803 "<transport> defaults to motorcar but can be set to:\n"
804 "%s"
805 "\n"
806 "<highway> can be selected from:\n"
807 "%s"
808 "\n"
809 "<property> can be selected from:\n"
810 "%s",
811 TransportList(),HighwayList(),PropertyList());
812
813 exit(!detail);
814 }

Properties

Name Value
cvs:description Router.