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 213 - (hide annotations) (download) (as text)
Thu Jul 2 16:33:31 2009 UTC (15 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 12063 byte(s)
Removed unused header files, change assert statements, tidy some code.

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

Properties

Name Value
cvs:description Router.