Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/router.c
Parent Directory
|
Revision Log
Revision 130 -
(hide annotations)
(download)
(as text)
Sat Feb 28 17:22:24 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 10613 byte(s)
Sat Feb 28 17:22:24 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 10613 byte(s)
Add new command line options to make it more CGI friendly.
1 | amb | 2 | /*************************************** |
2 | amb | 130 | $Header: /home/amb/CVS/routino/src/router.c,v 1.40 2009-02-28 17:22:24 amb Exp $ |
3 | amb | 2 | |
4 | OSM router. | ||
5 | ******************/ /****************** | ||
6 | Written by Andrew M. Bishop | ||
7 | |||
8 | amb | 3 | This file Copyright 2008,2009 Andrew M. Bishop |
9 | amb | 2 | It may be distributed under the GNU Public License, version 2, or |
10 | any higher version. See section COPYING of the GNU Public license | ||
11 | for conditions under which this file may be redistributed. | ||
12 | ***************************************/ | ||
13 | |||
14 | |||
15 | #include <stdio.h> | ||
16 | amb | 31 | #include <string.h> |
17 | amb | 2 | #include <stdlib.h> |
18 | amb | 121 | #include <math.h> |
19 | amb | 130 | #include <ctype.h> |
20 | amb | 2 | |
21 | amb | 96 | #include "types.h" |
22 | amb | 2 | #include "functions.h" |
23 | amb | 82 | #include "profiles.h" |
24 | amb | 115 | #include "nodes.h" |
25 | #include "segments.h" | ||
26 | amb | 109 | #include "ways.h" |
27 | amb | 2 | |
28 | |||
29 | amb | 113 | /*+ The option not to print any progress information. +*/ |
30 | amb | 107 | int option_quiet=0; |
31 | |||
32 | amb | 113 | /*+ The option to calculate the quickest route insted of the shortest. +*/ |
33 | int option_quickest=0; | ||
34 | amb | 107 | |
35 | amb | 113 | |
36 | amb | 2 | int main(int argc,char** argv) |
37 | { | ||
38 | amb | 95 | Nodes *OSMNodes; |
39 | Segments *OSMSegments; | ||
40 | Ways *OSMWays; | ||
41 | amb | 115 | index_t start,finish; |
42 | amb | 130 | float lon_start=999,lat_start=999,lon_finish=999,lat_finish=999; |
43 | amb | 129 | int help_profile=0,help_profile_js=0,all=0,super=0,no_print=0; |
44 | amb | 95 | char *dirname=NULL,*prefix=NULL,*filename; |
45 | amb | 82 | Transport transport=Transport_None; |
46 | Profile profile; | ||
47 | amb | 75 | int i; |
48 | amb | 2 | |
49 | amb | 44 | /* Parse the command line arguments */ |
50 | amb | 2 | |
51 | amb | 99 | if(argc<5) |
52 | amb | 2 | { |
53 | amb | 44 | usage: |
54 | amb | 75 | |
55 | amb | 130 | fprintf(stderr,"Usage: router [--lon1=]<start-lon> [--lat1=]<start-lat>\n" |
56 | " [--lon2=]<finish-lon> [--lon2=]<finish-lat>\n" | ||
57 | amb | 129 | " [--help | --help-profile | -help-profile-js]\n" |
58 | amb | 101 | " [--dir=<name>] [--prefix=<name>]\n" |
59 | amb | 122 | " [--shortest | --quickest]\n" |
60 | " [--all | --super]\n" | ||
61 | amb | 107 | " [--no-print] [--quiet]\n" |
62 | amb | 101 | " [--transport=<transport>]\n" |
63 | amb | 130 | " [--highway-<highway>=[0|1] ...]\n" |
64 | amb | 101 | " [--speed-<highway>=<speed> ...]\n" |
65 | amb | 130 | " [--oneway=[0|1]]\n" |
66 | amb | 75 | "\n" |
67 | amb | 82 | "<transport> defaults to motorcar but can be set to:\n" |
68 | amb | 75 | "%s" |
69 | "\n" | ||
70 | amb | 82 | "<highway> can be selected from:\n" |
71 | "%s" | ||
72 | amb | 103 | "\n" |
73 | amb | 82 | "<speed> is a speed in km/hour\n" |
74 | "\n", | ||
75 | amb | 75 | TransportList(),HighwayList()); |
76 | |||
77 | amb | 2 | return(1); |
78 | } | ||
79 | |||
80 | amb | 130 | /* Get the transport type if specified and fill in the default profile */ |
81 | amb | 75 | |
82 | amb | 130 | for(i=1;i<argc;i++) |
83 | amb | 101 | if(!strncmp(argv[i],"--transport=",12)) |
84 | amb | 82 | { |
85 | amb | 101 | transport=TransportType(&argv[i][12]); |
86 | amb | 75 | |
87 | amb | 82 | if(transport==Transport_None) |
88 | goto usage; | ||
89 | } | ||
90 | |||
91 | if(transport==Transport_None) | ||
92 | transport=Transport_Motorcar; | ||
93 | |||
94 | profile=*GetProfile(transport); | ||
95 | |||
96 | /* Parse the other command line arguments */ | ||
97 | |||
98 | amb | 130 | while(--argc>=1) |
99 | amb | 44 | { |
100 | amb | 130 | if(isdigit(argv[argc][0]) || |
101 | ((argv[argc][0]=='-' || argv[argc][0]=='+') && isdigit(argv[argc][1]))) | ||
102 | { | ||
103 | if(lon_finish==999) | ||
104 | lon_finish=(M_PI/180)*atof(argv[argc]); | ||
105 | else if(lat_finish==999) | ||
106 | lat_finish=(M_PI/180)*atof(argv[argc]); | ||
107 | else if(lon_start==999) | ||
108 | lon_start=(M_PI/180)*atof(argv[argc]); | ||
109 | else if(lat_start==999) | ||
110 | lat_start=(M_PI/180)*atof(argv[argc]); | ||
111 | else | ||
112 | goto usage; | ||
113 | } | ||
114 | else if(!strncmp(argv[argc],"--lat1=",7)) | ||
115 | lat_start=(M_PI/180)*atof(&argv[argc][7]); | ||
116 | else if(!strncmp(argv[argc],"--lon1=",7)) | ||
117 | lon_start=(M_PI/180)*atof(&argv[argc][7]); | ||
118 | else if(!strncmp(argv[argc],"--lat2=",7)) | ||
119 | lat_finish=(M_PI/180)*atof(&argv[argc][7]); | ||
120 | else if(!strncmp(argv[argc],"--lon2=",7)) | ||
121 | lon_finish=(M_PI/180)*atof(&argv[argc][7]); | ||
122 | else if(!strcmp(argv[argc],"--help")) | ||
123 | amb | 75 | goto usage; |
124 | amb | 101 | else if(!strcmp(argv[argc],"--help-profile")) |
125 | amb | 82 | help_profile=1; |
126 | amb | 129 | else if(!strcmp(argv[argc],"--help-profile-js")) |
127 | help_profile_js=1; | ||
128 | amb | 101 | else if(!strncmp(argv[argc],"--dir=",6)) |
129 | dirname=&argv[argc][6]; | ||
130 | else if(!strncmp(argv[argc],"--prefix=",9)) | ||
131 | prefix=&argv[argc][9]; | ||
132 | amb | 113 | else if(!strcmp(argv[argc],"--shortest")) |
133 | option_quickest=0; | ||
134 | else if(!strcmp(argv[argc],"--quickest")) | ||
135 | option_quickest=1; | ||
136 | amb | 122 | else if(!strcmp(argv[argc],"--all")) |
137 | all=1; | ||
138 | else if(!strcmp(argv[argc],"--super")) | ||
139 | amb | 124 | super=1; |
140 | amb | 101 | else if(!strcmp(argv[argc],"--no-print")) |
141 | amb | 82 | no_print=1; |
142 | amb | 107 | else if(!strcmp(argv[argc],"--quiet")) |
143 | option_quiet=1; | ||
144 | amb | 101 | else if(!strncmp(argv[argc],"--transport=",12)) |
145 | amb | 82 | ; /* Done this already*/ |
146 | amb | 130 | else if(!strncmp(argv[argc],"--highway-",10)) |
147 | amb | 75 | { |
148 | amb | 130 | Highway highway; |
149 | char *equal=strchr(argv[argc],'='); | ||
150 | char *string; | ||
151 | amb | 82 | |
152 | amb | 130 | if(!equal) |
153 | goto usage; | ||
154 | |||
155 | string=strcpy((char*)malloc(strlen(argv[argc])),argv[argc]+10); | ||
156 | string[equal-argv[argc]-10]=0; | ||
157 | |||
158 | highway=HighwayType(string); | ||
159 | |||
160 | free(string); | ||
161 | |||
162 | amb | 82 | if(highway==Way_Unknown) |
163 | goto usage; | ||
164 | |||
165 | amb | 130 | profile.highways[highway]=atoi(equal+1); |
166 | amb | 75 | } |
167 | amb | 101 | else if(!strncmp(argv[argc],"--speed-",8)) |
168 | amb | 82 | { |
169 | Highway highway; | ||
170 | char *equal=strchr(argv[argc],'='); | ||
171 | char *string; | ||
172 | |||
173 | if(!equal) | ||
174 | goto usage; | ||
175 | |||
176 | amb | 101 | string=strcpy((char*)malloc(strlen(argv[argc])),argv[argc]+8); |
177 | amb | 130 | string[equal-argv[argc]-8]=0; |
178 | amb | 82 | |
179 | highway=HighwayType(string); | ||
180 | |||
181 | free(string); | ||
182 | |||
183 | if(highway==Way_Unknown) | ||
184 | goto usage; | ||
185 | |||
186 | profile.speed[highway]=atoi(equal+1); | ||
187 | } | ||
188 | amb | 130 | else if(!strcmp(argv[argc],"--oneway")) |
189 | profile.oneway=1; | ||
190 | else if(!strncmp(argv[argc],"--oneway=",9)) | ||
191 | profile.oneway=atoi(&argv[argc][9]); | ||
192 | amb | 44 | else |
193 | goto usage; | ||
194 | } | ||
195 | |||
196 | amb | 82 | if(help_profile) |
197 | { | ||
198 | PrintProfile(&profile); | ||
199 | |||
200 | return(0); | ||
201 | } | ||
202 | amb | 129 | else if(help_profile_js) |
203 | { | ||
204 | PrintProfilesJS(); | ||
205 | amb | 82 | |
206 | amb | 129 | return(0); |
207 | } | ||
208 | |||
209 | amb | 2 | /* Load in the data */ |
210 | |||
211 | amb | 95 | filename=(char*)malloc((dirname?strlen(dirname):0)+(prefix?strlen(prefix):0)+16); |
212 | |||
213 | amb | 93 | sprintf(filename,"%s%s%s%snodes.mem",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":""); |
214 | OSMNodes=LoadNodeList(filename); | ||
215 | amb | 31 | |
216 | amb | 100 | if(!OSMNodes) |
217 | { | ||
218 | fprintf(stderr,"Cannot open nodes file '%s'.\n",filename); | ||
219 | return(1); | ||
220 | } | ||
221 | |||
222 | amb | 93 | sprintf(filename,"%s%s%s%ssegments.mem",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":""); |
223 | OSMSegments=LoadSegmentList(filename); | ||
224 | amb | 66 | |
225 | amb | 100 | if(!OSMSegments) |
226 | { | ||
227 | fprintf(stderr,"Cannot open segments file '%s'.\n",filename); | ||
228 | return(1); | ||
229 | } | ||
230 | |||
231 | amb | 93 | sprintf(filename,"%s%s%s%sways.mem",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":""); |
232 | OSMWays=LoadWayList(filename); | ||
233 | amb | 31 | |
234 | amb | 100 | if(!OSMWays) |
235 | { | ||
236 | fprintf(stderr,"Cannot open ways file '%s'.\n",filename); | ||
237 | return(1); | ||
238 | } | ||
239 | |||
240 | amb | 99 | /* Get the start and finish */ |
241 | |||
242 | amb | 107 | { |
243 | amb | 124 | distance_t dist_start=km_to_distance(10),dist_finish=km_to_distance(10); |
244 | amb | 99 | |
245 | amb | 124 | Node *start_node =FindNode(OSMNodes,lat_start ,lon_start ,&dist_start ); |
246 | Node *finish_node=FindNode(OSMNodes,lat_finish,lon_finish,&dist_finish); | ||
247 | amb | 107 | |
248 | if(!start_node) | ||
249 | { | ||
250 | fprintf(stderr,"Cannot find start node.\n"); | ||
251 | return(1); | ||
252 | } | ||
253 | |||
254 | if(!finish_node) | ||
255 | { | ||
256 | fprintf(stderr,"Cannot find finish node.\n"); | ||
257 | return(1); | ||
258 | } | ||
259 | |||
260 | if(!option_quiet) | ||
261 | { | ||
262 | float lat,lon; | ||
263 | |||
264 | GetLatLong(OSMNodes,start_node,&lat,&lon); | ||
265 | |||
266 | amb | 124 | printf("Start node : %3.6f %4.6f = %2.3f km\n",(180/M_PI)*lat,(180/M_PI)*lon,distance_to_km(dist_start)); |
267 | amb | 107 | |
268 | GetLatLong(OSMNodes,finish_node,&lat,&lon); | ||
269 | |||
270 | amb | 124 | printf("Finish node: %3.6f %4.6f = %2.3f km\n",(180/M_PI)*lat,(180/M_PI)*lon,distance_to_km(dist_finish)); |
271 | amb | 107 | } |
272 | |||
273 | start =IndexNode(OSMNodes,start_node ); | ||
274 | finish=IndexNode(OSMNodes,finish_node); | ||
275 | amb | 126 | |
276 | if(super && !IsSuperNode(start_node) && !IsSuperNode(finish_node)) | ||
277 | { | ||
278 | fprintf(stderr,"Start and/or finish nodes are not super-nodes.\n"); | ||
279 | return(1); | ||
280 | } | ||
281 | amb | 107 | } |
282 | |||
283 | amb | 97 | /* Calculate the route. */ |
284 | |||
285 | amb | 54 | if(all) |
286 | amb | 31 | { |
287 | amb | 34 | Results *results; |
288 | |||
289 | amb | 31 | /* Calculate the route */ |
290 | amb | 2 | |
291 | amb | 82 | results=FindRoute(OSMNodes,OSMSegments,OSMWays,start,finish,&profile,all); |
292 | amb | 2 | |
293 | amb | 31 | /* Print the route */ |
294 | amb | 2 | |
295 | amb | 77 | if(!results) |
296 | { | ||
297 | amb | 112 | fprintf(stderr,"Cannot find route compatible with profile.\n"); |
298 | amb | 77 | return(1); |
299 | } | ||
300 | amb | 82 | else if(!no_print) |
301 | amb | 90 | PrintRoute(results,OSMNodes,OSMSegments,OSMWays,start,finish,&profile); |
302 | amb | 31 | } |
303 | else | ||
304 | { | ||
305 | amb | 48 | Results *begin,*end; |
306 | amb | 2 | |
307 | amb | 34 | /* Calculate the beginning of the route */ |
308 | amb | 31 | |
309 | amb | 95 | if(IsSuperNode(LookupNode(OSMNodes,start))) |
310 | amb | 34 | { |
311 | Result *result; | ||
312 | amb | 31 | |
313 | amb | 71 | begin=NewResultsList(1); |
314 | amb | 34 | |
315 | result=InsertResult(begin,start); | ||
316 | |||
317 | result->node=start; | ||
318 | amb | 113 | result->prev=0; |
319 | result->next=0; | ||
320 | result->distance=0; | ||
321 | result->duration=0; | ||
322 | amb | 34 | } |
323 | else | ||
324 | amb | 112 | { |
325 | amb | 126 | begin=FindStartRoutes(OSMNodes,OSMSegments,OSMWays,start,&profile); |
326 | amb | 34 | |
327 | amb | 112 | if(!begin) |
328 | { | ||
329 | fprintf(stderr,"Cannot find initial section of route compatible with profile.\n"); | ||
330 | return(1); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | amb | 34 | if(FindResult(begin,finish)) |
335 | { | ||
336 | /* Print the route */ | ||
337 | |||
338 | amb | 82 | if(!no_print) |
339 | amb | 95 | PrintRoute(begin,OSMNodes,OSMSegments,OSMWays,start,finish,&profile); |
340 | amb | 34 | } |
341 | else | ||
342 | { | ||
343 | amb | 55 | Results *superresults; |
344 | amb | 48 | |
345 | amb | 34 | /* Calculate the end of the route */ |
346 | |||
347 | amb | 95 | if(IsSuperNode(LookupNode(OSMNodes,finish))) |
348 | amb | 34 | { |
349 | Result *result; | ||
350 | |||
351 | amb | 71 | end=NewResultsList(1); |
352 | amb | 34 | |
353 | result=InsertResult(end,finish); | ||
354 | |||
355 | result->node=finish; | ||
356 | amb | 113 | result->prev=0; |
357 | result->next=0; | ||
358 | result->distance=0; | ||
359 | result->duration=0; | ||
360 | amb | 34 | } |
361 | else | ||
362 | amb | 112 | { |
363 | amb | 126 | end=FindFinishRoutes(OSMNodes,OSMSegments,OSMWays,finish,&profile); |
364 | amb | 34 | |
365 | amb | 112 | if(!end) |
366 | { | ||
367 | fprintf(stderr,"Cannot find final section of route compatible with profile.\n"); | ||
368 | return(1); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | amb | 34 | /* Calculate the middle of the route */ |
373 | |||
374 | amb | 95 | superresults=FindRoute3(OSMNodes,OSMSegments,OSMWays,start,finish,begin,end,&profile); |
375 | amb | 34 | |
376 | /* Print the route */ | ||
377 | |||
378 | amb | 77 | if(!superresults) |
379 | { | ||
380 | amb | 112 | fprintf(stderr,"Cannot find route compatible with profile.\n"); |
381 | amb | 77 | return(1); |
382 | } | ||
383 | amb | 82 | else if(!no_print) |
384 | amb | 55 | { |
385 | amb | 124 | if(super) |
386 | amb | 82 | { |
387 | amb | 95 | PrintRoute(superresults,OSMNodes,OSMSegments,OSMWays,start,finish,&profile); |
388 | amb | 82 | } |
389 | else | ||
390 | { | ||
391 | Results *results=CombineRoutes(superresults,OSMNodes,OSMSegments,OSMWays,start,finish,&profile); | ||
392 | amb | 55 | |
393 | amb | 95 | PrintRoute(results,OSMNodes,OSMSegments,OSMWays,start,finish,&profile); |
394 | amb | 82 | } |
395 | amb | 55 | } |
396 | amb | 34 | } |
397 | amb | 31 | } |
398 | |||
399 | amb | 2 | return(0); |
400 | } |
Properties
Name | Value |
---|---|
cvs:description | Router. |