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 290 - (hide annotations) (download) (as text)
Sat Oct 24 10:44:48 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 11149 byte(s)
Fix missing segments in output if start and finish points are found by the start
search.

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

Properties

Name Value
cvs:description Router.