Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/router.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 828 - (hide annotations) (download) (as text)
Sun Aug 21 14:49:20 2011 UTC (13 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 24355 byte(s)
Merge version 2.0.3 into working version.

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

Properties

Name Value
cvs:description Router.