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 165 - (show annotations) (download) (as text)
Mon Apr 27 18:56:39 2009 UTC (15 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 12274 byte(s)
Allow generating a route with intermediate waypoints.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/router.c,v 1.47 2009-04-27 18:56:39 amb Exp $
3
4 OSM router.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008,2009 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 <math.h>
29 #include <ctype.h>
30
31 #include "types.h"
32 #include "functions.h"
33 #include "profiles.h"
34 #include "nodes.h"
35 #include "segments.h"
36 #include "ways.h"
37
38
39 /*+ The option not to print any progress information. +*/
40 int option_quiet=0;
41
42 /*+ The option to calculate the quickest route insted of the shortest. +*/
43 int option_quickest=0;
44
45
46 int main(int argc,char** argv)
47 {
48 Nodes *OSMNodes;
49 Segments *OSMSegments;
50 Ways *OSMWays;
51 Results *results[9]={NULL};
52 int point_used[9]={0};
53 float point_lon[9],point_lat[9];
54 int help_profile=0,help_profile_js=0,help_profile_pl=0;
55 int option_all=0,option_super=0,option_no_output=0;
56 char *dirname=NULL,*prefix=NULL,*filename;
57 Transport transport=Transport_None;
58 Profile profile;
59 Node *start_node=NULL,*finish_node=NULL;
60 int arg,node;
61
62 /* Parse the command line arguments */
63
64 if(argc<2)
65 {
66 usage:
67
68 fprintf(stderr,"Usage: router [--lon1=]<longitude> [--lat1=]<latitude>\n"
69 " [--lon2=]<longitude> [--lon2=]<latitude>\n"
70 " [ ... [--lon9=]<longitude> [--lon9=]<latitude> ]\n"
71 " [--help | --help-profile | --help-profile-js | --help-profile-pl]\n"
72 " [--dir=<name>] [--prefix=<name>]\n"
73 " [--shortest | --quickest]\n"
74 " [--all | --super]\n"
75 " [--no-output] [--quiet]\n"
76 " [--transport=<transport>]\n"
77 " [--highway-<highway>=[0|1] ...]\n"
78 " [--speed-<highway>=<speed> ...]\n"
79 " [--oneway=[0|1]]\n"
80 " [--weight=<weight>]\n"
81 " [--height=<height>] [--width=<width>] [--length=<length>]\n"
82 "\n"
83 "<transport> defaults to motorcar but can be set to:\n"
84 "%s"
85 "\n"
86 "<highway> can be selected from:\n"
87 "%s"
88 "\n"
89 "<speed> is a speed in km/hour\n"
90 "<weight> is a weight in tonnes\n"
91 "<height>, <width>, <length> are dimensions in metres\n"
92 "\n",
93 TransportList(),HighwayList());
94
95 return(1);
96 }
97
98 /* Get the transport type if specified and fill in the default profile */
99
100 for(arg=1;arg<argc;arg++)
101 if(!strncmp(argv[arg],"--transport=",12))
102 {
103 transport=TransportType(&argv[arg][12]);
104
105 if(transport==Transport_None)
106 goto usage;
107 }
108
109 if(transport==Transport_None)
110 transport=Transport_Motorcar;
111
112 profile=*GetProfile(transport);
113
114 /* Parse the other command line arguments */
115
116 for(arg=1;arg<argc;arg++)
117 {
118 if(isdigit(argv[arg][0]) ||
119 ((argv[arg][0]=='-' || argv[arg][0]=='+') && isdigit(argv[arg][1])))
120 {
121 for(node=0;node<sizeof(point_used)/sizeof(point_used[0]);node++)
122 if(point_used[node]!=3)
123 {
124 if(point_used[node]==0)
125 {
126 point_lon[node]=(M_PI/180)*atof(argv[arg]);
127 point_used[node]=1;
128 }
129 else /* if(point_used[node]==1) */
130 {
131 point_lat[node]=(M_PI/180)*atof(argv[arg]);
132 point_used[node]=3;
133 }
134 break;
135 }
136 }
137 else if(!strncmp(argv[arg],"--lon",5) && isdigit(argv[arg][5]) && argv[arg][6]=='=')
138 {
139 node=atoi(&argv[arg][5]);
140 if(point_used[node]&1)
141 goto usage;
142 point_lon[node]=(M_PI/180)*atof(&argv[arg][7]);
143 point_used[node]+=1;
144 }
145 else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5]) && argv[arg][6]=='=')
146 {
147 node=atoi(&argv[arg][5]);
148 if(point_used[node]&2)
149 goto usage;
150 point_lat[node]=(M_PI/180)*atof(&argv[arg][7]);
151 point_used[node]+=2;
152 }
153 else if(!strcmp(argv[arg],"--help"))
154 goto usage;
155 else if(!strcmp(argv[arg],"--help-profile"))
156 help_profile=1;
157 else if(!strcmp(argv[arg],"--help-profile-js"))
158 help_profile_js=1;
159 else if(!strcmp(argv[arg],"--help-profile-pl"))
160 help_profile_pl=1;
161 else if(!strncmp(argv[arg],"--dir=",6))
162 dirname=&argv[arg][6];
163 else if(!strncmp(argv[arg],"--prefix=",9))
164 prefix=&argv[arg][9];
165 else if(!strcmp(argv[arg],"--shortest"))
166 option_quickest=0;
167 else if(!strcmp(argv[arg],"--quickest"))
168 option_quickest=1;
169 else if(!strcmp(argv[arg],"--all"))
170 option_all=1;
171 else if(!strcmp(argv[arg],"--super"))
172 option_super=1;
173 else if(!strcmp(argv[arg],"--no-output"))
174 option_no_output=1;
175 else if(!strcmp(argv[arg],"--quiet"))
176 option_quiet=1;
177 else if(!strncmp(argv[arg],"--transport=",12))
178 ; /* Done this already*/
179 else if(!strncmp(argv[arg],"--highway-",10))
180 {
181 Highway highway;
182 char *equal=strchr(argv[arg],'=');
183 char *string;
184
185 if(!equal)
186 goto usage;
187
188 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10);
189 string[equal-argv[arg]-10]=0;
190
191 highway=HighwayType(string);
192
193 free(string);
194
195 if(highway==Way_Unknown)
196 goto usage;
197
198 profile.highways[highway]=atoi(equal+1);
199 }
200 else if(!strncmp(argv[arg],"--speed-",8))
201 {
202 Highway highway;
203 char *equal=strchr(argv[arg],'=');
204 char *string;
205
206 if(!equal)
207 goto usage;
208
209 string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8);
210 string[equal-argv[arg]-8]=0;
211
212 highway=HighwayType(string);
213
214 free(string);
215
216 if(highway==Way_Unknown)
217 goto usage;
218
219 profile.speed[highway]=atoi(equal+1);
220 }
221 else if(!strncmp(argv[arg],"--oneway=",9))
222 profile.oneway=atoi(&argv[arg][9]);
223 else if(!strncmp(argv[arg],"--weight=",9))
224 profile.weight=tonnes_to_weight(atof(&argv[arg][9]));
225 else if(!strncmp(argv[arg],"--height=",9))
226 profile.height=metres_to_height(atof(&argv[arg][9]));
227 else if(!strncmp(argv[arg],"--width=",8))
228 profile.width=metres_to_width(atof(&argv[arg][8]));
229 else if(!strncmp(argv[arg],"--length=",9))
230 profile.length=metres_to_length(atof(&argv[arg][9]));
231 else
232 goto usage;
233 }
234
235 for(node=0;node<sizeof(point_used)/sizeof(point_used[0]);node++)
236 if(point_used[node]==1 || point_used[node]==2)
237 goto usage;
238
239 if(help_profile)
240 {
241 PrintProfile(&profile);
242
243 return(0);
244 }
245 else if(help_profile_js)
246 {
247 PrintProfilesJS();
248
249 return(0);
250 }
251 else if(help_profile_pl)
252 {
253 PrintProfilesPerl();
254
255 return(0);
256 }
257
258 /* Load in the data */
259
260 OSMNodes=LoadNodeList(filename=FileName(dirname,prefix,"nodes.mem"));
261
262 if(!OSMNodes)
263 {
264 fprintf(stderr,"Cannot open nodes file '%s'.\n",filename);
265 return(1);
266 }
267
268 OSMSegments=LoadSegmentList(filename=FileName(dirname,prefix,"segments.mem"));
269
270 if(!OSMSegments)
271 {
272 fprintf(stderr,"Cannot open segments file '%s'.\n",filename);
273 return(1);
274 }
275
276 OSMWays=LoadWayList(filename=FileName(dirname,prefix,"ways.mem"));
277
278 if(!OSMWays)
279 {
280 fprintf(stderr,"Cannot open ways file '%s'.\n",filename);
281 return(1);
282 }
283
284 /* Loop through all pairs of nodes */
285
286 for(node=0;node<sizeof(point_used)/sizeof(point_used[0]);node++)
287 {
288 distance_t dist=km_to_distance(10);
289 index_t start,finish;
290
291 if(point_used[node]!=3)
292 continue;
293
294 /* Find the node */
295
296 start_node=finish_node;
297
298 finish_node=FindNode(OSMNodes,point_lat[node],point_lon[node],&dist);
299
300 if(!finish_node)
301 {
302 fprintf(stderr,"Cannot find node close to specified point %d.\n",node);
303 return(1);
304 }
305
306 if(!option_quiet)
307 {
308 float lat,lon;
309
310 GetLatLong(OSMNodes,finish_node,&lat,&lon);
311
312 printf("Node %d: %3.6f %4.6f = %2.3f km\n",node,(180.0/M_PI)*lat,(180.0/M_PI)*lon,distance_to_km(dist));
313 }
314
315 if(!start_node || !finish_node)
316 continue;
317
318 /* Find the route segment */
319
320 start =IndexNode(OSMNodes,start_node );
321 finish=IndexNode(OSMNodes,finish_node);
322
323 if(option_super && !IsSuperNode(start_node) && !IsSuperNode(finish_node))
324 {
325 fprintf(stderr,"Start and/or finish nodes are not super-nodes.\n");
326 return(1);
327 }
328
329 /* Calculate the route. */
330
331 if(option_all)
332 {
333 /* Calculate the route */
334
335 results[node]=FindRoute(OSMNodes,OSMSegments,OSMWays,start,finish,&profile,option_all);
336
337 if(!results[node])
338 {
339 fprintf(stderr,"Cannot find route compatible with profile.\n");
340 return(1);
341 }
342 }
343 else
344 {
345 Results *begin,*end;
346
347 /* Calculate the beginning of the route */
348
349 if(IsSuperNode(LookupNode(OSMNodes,start)))
350 {
351 Result *result;
352
353 begin=NewResultsList(1);
354
355 begin->start=start;
356
357 result=InsertResult(begin,start);
358
359 result->node=start;
360 result->prev=0;
361 result->next=0;
362 result->distance=0;
363 result->duration=0;
364 }
365 else
366 {
367 begin=FindStartRoutes(OSMNodes,OSMSegments,OSMWays,start,&profile);
368
369 if(!begin)
370 {
371 fprintf(stderr,"Cannot find initial section of route compatible with profile.\n");
372 return(1);
373 }
374 }
375
376 if(FindResult(begin,finish))
377 {
378 results[node]=begin;
379
380 results[node]->finish=finish;
381 }
382 else
383 {
384 Results *superresults;
385
386 /* Calculate the end of the route */
387
388 if(IsSuperNode(LookupNode(OSMNodes,finish)))
389 {
390 Result *result;
391
392 end=NewResultsList(1);
393
394 end->finish=finish;
395
396 result=InsertResult(end,finish);
397
398 result->node=finish;
399 result->prev=0;
400 result->next=0;
401 result->distance=0;
402 result->duration=0;
403 }
404 else
405 {
406 end=FindFinishRoutes(OSMNodes,OSMSegments,OSMWays,finish,&profile);
407
408 if(!end)
409 {
410 fprintf(stderr,"Cannot find final section of route compatible with profile.\n");
411 return(1);
412 }
413 }
414
415 /* Calculate the middle of the route */
416
417 superresults=FindRoute3(OSMNodes,OSMSegments,OSMWays,begin,end,&profile);
418
419 if(!superresults)
420 {
421 fprintf(stderr,"Cannot find route compatible with profile.\n");
422 return(1);
423 }
424
425 if(option_super)
426 results[node]=superresults;
427 else
428 results[node]=CombineRoutes(superresults,OSMNodes,OSMSegments,OSMWays,&profile);
429 }
430 }
431 }
432
433 if(!option_no_output)
434 {
435 PrintRouteHead(FileName(dirname,prefix,"copyright.txt"));
436
437 for(node=1;node<sizeof(point_used)/sizeof(point_used[0]);node++)
438 if(results[node])
439 PrintRoute(results[node],OSMNodes,OSMSegments,OSMWays,&profile);
440
441 PrintRouteTail();
442 }
443
444 return(0);
445 }

Properties

Name Value
cvs:description Router.