Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /branches/destination-access/src/router.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1465 - (hide annotations) (download) (as text)
Fri Aug 2 18:12:56 2013 UTC (11 years, 7 months ago) by amb
Original Path: trunk/src/router.c
File MIME type: text/x-csrc
File size: 24933 byte(s)
Add a '--output-stdout' option.

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

Properties

Name Value
cvs:description Router.